2

My code is like this:

(defun test () "Test."
  (setq lista '(A))
  (push 'B lista)
  (nreverse lista))

(message "%s" (test))  ; Output is (A B)
(message "%s" (test))  ; Output is (B A B)

It seems strange because I expect the result to be

(A B)
(A B)

If I substitute (setq lista '(A)) with (setq lista (list 'A)), I get the result expected. I think the list creating methods cause the difference but I don't know the detail.

My emacs version is GNU Emacs 24.5.1

hw9527
  • 35
  • 4
  • Your question already has the answer: `quote` does not *create* anything, it only lets you refer to a value hardcoded into the code. – Stefan Aug 05 '17 at 19:41

1 Answers1

3

You're doing this:

(defvar t1 '(A))
(defun test ()
  "Test."
  (setq lista t1)
  (push 'B lista)
  (nreverse lista))

You modify a cons cell that's part of the code: after the first call, t1 becomes '(A B).

Avoid it by using (list) instead of (quote):

(defun test ()
  "Test."
  (setq lista (list 'A))
  (push 'B lista)
  (nreverse lista))
abo-abo
  • 20,038
  • 3
  • 50
  • 71
  • It sounds reasonable. So you mean elisp will create temporary variable when creating list using quote expression in local scope, but this doesn't happen in global scope. Why elisp makes them different because it is a bit confusing. – hw9527 Aug 01 '17 at 12:38
  • The temporary variable is created by the reader each time it encounters a quote. It's not quite temporary though: it's part of the function definition. So when you run the function, you modify your function definition. – abo-abo Aug 01 '17 at 14:06