30

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))
  • 5
    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
  • 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
  • @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
  • @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
30

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.

19

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.

  • 3
    Good point on consing. 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
  • @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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.