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))
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityThe 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)
yieldsx
. 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.
'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.
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.
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.
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
.
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. :-)
`(,x . ,y)
.