I just spent a significant amount of time debugging an issue that boils down to the following:
(defun my-new-alist ()
`((x . nil)))
(setq a (my-new-alist))
(setq b (my-new-alist))
(push 1 (alist-get 'x a))
b ;; ((x . 1))
I expected a
and b
to be independent of each other (that is, I expected my-new-alist
to be pure. Instead, it seems to create a new list when the defun is executed, and always return a reference to that very list. Part of my confusion stems from comparing with the following:
(defun my-new-list ()
nil)
(setq a (my-new-list))
(setq b (my-new-list))
(push 1 a)
a ;; => (1)
b ;; => nil
Note also that anti-quoting the nil part fixes the issue, it seems; that is, the following function doesn't exhibit the problem:
(defun my-new-alist ()
`((x . ,nil)))
What is the significant difference between the list and alist examples? Which parts of the ELisp manual discuss this issue? Why does antiquoting the nil
part fix things?
This question is similar to, but not the same as, Proper reinitialization of a list? What is happening under the hood?. The answers to that question doesn't discuss why using nil
isn't a problem, nor do they explain why antiquoting nil makes a difference. Additionally, I am looking for references in the Emacs lisp manual.
(backquote (form))
behaves the same as(quote (form))
when there are no evaluated or spliced components. Therefore see emacs.stackexchange.com/q/20535 and also related Q&As stackoverflow.com/q/36964728 (for hash tables) and stackoverflow.com/q/18790192 (not elisp specific).(list (list 'x))
, andlist
creates new list structure when invoked.