I'm teaching myself some more elisp and have encountered the following problem:
If I want to reset a list variable it won't get updated after the first evaluation. Here is some example code:
(defun initilize ()
(setq example '(3)))
(defun modify ()
(initilize)
(message "%S" example)
(setcar example 2))
; M-x eval-buffer RET
(modify) ; message --> (3)
(modify) ; message --> (2)
(modify) ; message --> (2)
I'm interested in two things. The first is to learn more about what is happening "under the hood" so why does it work the first time and fails on subsequent calls?
The second and more practical question is how to reinitialize the list properly or is there another common way of doing something like that?
One workaround I found myself is to use a quoted list and evaluating the content like this:
(setq example `(,3))
'(some list)
to beeq
to'(some list)
- ever.There is generally no guarantee in Lisp that code that visibly quotes a list returns new list structure each time. In some Lisp implementations it might, or it might some of the time. In others, it never does. Your code should anyway not depend on any such behavior from the implementation. If you want new list structure, uselist
orcons
or equivalent.example
has never been declared as a variable, sosetq
must be acting as if it declares a new variable, but later on when you callinitialize
again a new variable is being created, whilemodify
remembers the old one... in any case this is not an expected behavior, however, the use ofsetq
with something that hasn't been introduced earlier as a variable might as well be undefined.'(3)
is treated as a literal value, so once you(setcar '(3) 2)
, whenever you do(defvar foo '(3))
or(let ((foo '(3)))
and so on you will likely get a value offoo
equal to'(2)
. I say "likely" because this behavior isn't guaranteed, it's a kind of optimization that the interpreter does whenever it feels like, something known as constants subexpression elimination (a particular case of). So, what abo-abo wrote is not exactly the reason. It's more like modifying a string literal in C (which typically generates a warning).