Some Lisp objects should never change. For example, the Lisp
expression "aaa"
yields a string, but you should not change
its contents. And some objects cannot be changed; for example,
although you can create a new number by calculating one, Lisp provides
no operation to change the value of an existing number.
Other Lisp objects are mutable: it is safe to change their values via destructive operations involving side effects. For example, an existing marker can be changed by moving the marker to point to somewhere else.
Although numbers never change and all markers are mutable,
some types have members some of which are mutable and others not. These
types include conses, vectors, and strings. For example,
although "cons"
and (symbol-name 'cons)
both yield
strings that should not be changed, (copy-sequence "cons")
and
(make-string 3 ?a)
both yield mutable strings that can be
changed via later calls to aset
.
A mutable object stops being mutable if it is part of an expression that is evaluated. For example:
(let* ((x (list 0.5)) (y (eval (list 'quote x)))) (setcar x 1.5) ;; The program should not do this. y)
Although the list (0.5)
was mutable when it was created, it should not
have been changed via setcar
because it was given to eval
. The
reverse does not occur: an object that should not be changed never
becomes mutable afterwards.
If a program attempts to change objects that should not be changed, the resulting behavior is undefined: the Lisp interpreter might signal an error, or it might crash or behave unpredictably in other ways.2
When similar constants occur as parts of a program, the Lisp
interpreter might save time or space by reusing existing constants or
their components. For example, (eq "abc" "abc")
returns
t
if the interpreter creates only one instance of the string
literal "abc"
, and returns nil
if it creates two
instances. Lisp programs should be written so that they work
regardless of whether this optimization is in use.
This is the behavior specified for languages like Common Lisp and C for constants, and this differs from languages like JavaScript and Python where an interpreter is required to signal an error if a program attempts to change an immutable object. Ideally the Emacs Lisp interpreter will evolve in latter direction.