41

The below obviously doesn't work and hence this question.

How do I correct the below code so that the value of somelist becomes '(("abc" . 123)) ?

(setq x "abc")
(setq y 123)
(setq somelist nil)
(add-to-list 'somelist '(x . y))
Drew
  • 75,699
  • 9
  • 109
  • 225
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
  • 6
    Have you tried quasiquoting? Try `\`(,x . ,y)`. – Dan Jan 17 '15 at 21:13
  • Ah, that's what I missed. I didn't know what to google for :). I tried `(add-to-list 'somelist '(,x . ,y))` but forgot the backquote. – Kaushal Modi Jan 17 '15 at 21:17
  • 2
    Questions considered as duplicates of this one recur very often. Can someone come up with a way to make it more clear to beginners that this question/answer is what they're looking for? I suspect part of the problem is that the title of this question only makes sense if you already know the root cause of the problem (i.e. you kind of know the answer). I'm trying to imagine myself as a user who has no idea that variables need to be evaluated and even less of an idea what the "quote" means, but am coming empty. @Drew? – Stefan Oct 10 '18 at 13:04
  • 1
    @stefan: Unlike the case where there is an error message (which can be used in the question title of a community Q+A), the error, if any, resulting from quoting something that needs to be evaluated (and this is a particular case of that) can be far afield of the site of the quoting. More commonly, there is no (Emacs) error - just behavior that doesn't correspond to what the user wanted. – Drew Oct 10 '18 at 14:36
  • 1
    @Stefan: No great question title comes to mind for this. But we could at least formulate a question that tackles it directly, including perhaps a "normal" case that call for just removing a quote mark and a case that calls for quasiquoting. A good Q, covering such cases, and a good answer covering them, would be helpful. But as for finding Qs that are duplicates: without an error message in the Q title it requires reading the whole question and knowing how to find the duplicate to point to. – Drew Oct 10 '18 at 14:40
  • @stefan: Maybe there is a good way to find the duplicate to point to? Maybe we could have a list of questions that are commonly duplicated, to search through? – Drew Oct 10 '18 at 14:40
  • @stefan: There is also the similar but reverse problem of not quoting when quoting is needed. That's less common, I guess. – Drew Oct 10 '18 at 14:41
  • @stefan: Also, things can be deceiving. There are many questions that mention void function or void variable errors, but the answers are necessarily different, and they range from misspellings to missing load/require etc. – Drew Oct 10 '18 at 14:42
  • @Drew: Now that I think about it, maybe looking at the list of titles of all the post that were marked duplicates of this one might give us an idea of what a useful title for this one could look like. But I don't know how to get this list. – Stefan Oct 10 '18 at 14:57
  • @stefan: I don't know either. I know little about SE, meta SE, or how to use SE well. I know you can search by tags - that's what I often try, to find duplicates. But that helps only if one of us tagged a question in a relevant way before calling it a duplicate. Maybe there's a way to find Qs declared duplicates. Maybe we can add a "meta" tag for that, if not. (Not sure that would be worth it.) – Drew Oct 10 '18 at 16:04
  • @dan: This question (with this answer - the same general question sometimes has different correct answers) is frequently posed as a duplicate, but in other forms. It would be good for someone to make it Community and express it in more general form. – Drew Jan 13 '19 at 16:59
  • Hi @Drew : that would be fine. If you would like to edit it as such, I can mark it as Community. – Dan Jan 14 '19 at 12:19
  • @Dan: I'm too lazy. ;-) – Drew Jan 14 '19 at 14:43
  • @Drew (and Stefan): Regarding finding questions marked as duplicates, you can use the linked questions sidebar at right, or the [full list here](https://emacs.stackexchange.com/questions/linked/7481?lq=1). That will also include questions linked to from this question (none currently) as well as normal links to this question from other questions (that were not closed as duplicate). Should be a good place to start though. – Scott Weldon May 06 '20 at 22:10
  • FWIW, this question seems general enough to me as is to be a good dup target. – Scott Weldon May 06 '20 at 22:12
  • @ScottWeldon: Not sure what you mean by "dup target". When we close another question as a duplicate for this topic, this is typically (always?) the question we link to, as already expressing the question, i.e., the new question is closed as a dup of this one. Is that what you mean by "dup target", or were you suggesting to close this one as a dup of some other one. – Drew May 06 '20 at 23:24
  • @Drew: Apologies, I was overly concise. I meant "duplicate target", as in yes, other questions are closed as duplicates of this one. I think I misread the comments above to mean that you were considering finding another "canonical duplicate target" for this problem, rather than editing this question. – Scott Weldon May 07 '20 at 17:26
  • So let's try this again: I think this question is general enough as currently written, and doesn't need any major edits. Looking at a few of the most-recently linked questions, excluding the ones that aren't actually duplicates, most of them seem pretty obvious to me, so if the question authors didn't find this question as is, I don't think any edits would have helped that. The only change I can think of would be to clarify this also works for function calls, not just variable values, but that may already be covered by other duplicates. – Scott Weldon May 07 '20 at 17:27
  • (In case you weren't aware, per [the blog](https://stackoverflow.blog/2010/11/16/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/), *some* duplicates are actually a good thing, because having multiple variants of a question can help people searching be more likely to find it. It can even be okay to have answers on those duplicate questions to address variations; for example, [this answer helped me figure out how to apply this syntax to `org-capture-templates`](https://emacs.stackexchange.com/a/38758/675).) – Scott Weldon May 07 '20 at 17:29
  • 1
    @ScottWeldon: It would be good for the Q&A for this common topic to not _seem_ to be about just, say, variables. That's all I meant. This question could be edited to better reflect the underlying (more general) question. The rationales: (1) make it easier to find and (2) present the problem & solution(s) at a more useful level of generality. But I agree that this question is the best one we have for this problem. Thanks for the point and link about the value of dups. – Drew May 07 '20 at 20:57

2 Answers2

42

The general issue is that you need x and y to be evaluated before they get inserted in somelist. The issue with the quoted list (with ' as reader syntax) is that quote is a special form that does not evaluate its argument. According to the docstring:

(quote ARG)

Return the argument, without evaluating it. (quote x) yields x. Warning: quote does not construct its return value, but just returns the value that was pre-constructed by the Lisp reader...

Hence, you either need to backquote or use a function that evaluates the arguments.

Backquoting allows you to evaluate elements of a backquoted list selectively with the , syntax:

(setq x "x-val" y "y-val" z "z-val" somelist nil)
'(x  y z)                            ; => (x y z)
`(x ,y z)                            ; => (x "y-val" z)
(add-to-list 'somelist `(x y ,z))    ; => ((x y "z-val"))

Alternately, you can use cons (as @tarsius suggests in his answer) or, for an arbitrary number of elements, list:

(add-to-list 'somelist (cons x y))   ; => (("x-val" . "y-val"))
(setq somelist nil)                  ; reset
(add-to-list 'somelist (list x y z)) ; => (("x-val" "y-val" "z-val"))

Which to use depends on what you need to do with the elements.

Dan
  • 32,584
  • 6
  • 98
  • 168
  • Sorry, I have read this and other answers over and over, but am still clueless how to do that. That's because everywhere lists are used, but what if I don't have lists? What if I have just the `'x` from your answer. No lists, `'x` is an argument passed to a function *(like `(foo 'x)`)*, and inside the function I need *both* the `'x` *(to mutate it)*, and the value of `x` which is `"x-val"` in your code. So, no lists. Then, how do I get the value of `'x` out of it *(i.e. evaluate it)*? I tried a bunch of combinations with backticks, commas, and `@`s, to no avail. – Hi-Angel Aug 09 '21 at 20:38
  • I found out: one needs `eval`. So, calling `(eval 'x)` will return `"x-val"`. Worth mentioning in the answer I think, because similar questions are marked as duplicates of this page. – Hi-Angel Aug 10 '21 at 06:29
21

Do not quote the cons cell, because quoted expressions are not evaluated. That's exactly why one quotes - to prevent evaluation. But that's not what you want, so don't.

Instead use the form that creates a cons cell from two evaluated values, its arguments.

(cons x y)

Of course you can also quasiquote but that doesn't really make sense here, and looks worse. Only use ` and , when that improves readability, i.e. when doing something more complex than constructing a cons cell or adding an atom or list at the beginning of some existing list.

Using quasiquoting it would look like this:

`(,x . ,y)

Which is worse because it uses additional syntax which isn't required at all in this case and obfuscates that cons is being used.

tarsius
  • 25,298
  • 4
  • 69
  • 109
  • 3
    Good point on `cons`ing. Quasiquoting strikes me as being more about fine-grained control of the list contents rather than readability, but I agree that the use-case makes sense for `cons`. – Dan Jan 17 '15 at 23:02
  • Thank you for your answer. That was a great TIL moment for me. I was blindly putting quotes before lists and cons. – Kaushal Modi Jan 17 '15 at 23:02
  • 1
    @Dan, well yes - and no. Quasiquoting cannot do anything that you couldn't do with just `cons`, `list`, and `nconc`. Except being prettier. It's syntactic sugar which is useful when you need "fine-grained control of the list contents" (as in "doing something more complex than adding an atom or list at the beginning"). And the added benefit of using that syntactic sugar is: readability. Quasiquoting doesn't give you additional more fine-grained control - it just allows you to do the same thing with fewer bugs in the initial attempt. :-) – tarsius Jun 22 '15 at 18:23