Why does this function return a different value every time?
'(0 0 0)
is a literal object, which is assumed to be a constant (albeit not protected from modification). So you're effectively modifying the same object every time. To create different objects at each function call use (list 0 0 0)
.
So unless you know, what you're doing, you should always use literal lists (like '(0 0 0)
) only as constants.
On a side note, defining this function in the sbcl REPL you get the following warning:
caught WARNING:
Destructive function SB-KERNEL:%RPLACA called on constant data.
See also:
The ANSI Standard, Special Operator QUOTE
The ANSI Standard, Section 3.2.2.3
Which gives a good hint towards the problem at hand.
'(0 0 0)
in code is literal data. Modifying this data has undefined behavior. Common Lisp implementations may not detect it at runtime (unless data is for example placed in some read-only memory space). But it can have undesirable effects.
you see that this data may be (and often is) shared across various invocations of the same function
one of the more subtle possible errors is this: Common Lisp has been defined with various optimizations which can be done by a compiler in mind. For example a compiler is allowed to reuse data:
Example:
(let ((a '(1 2 3))
(b '(1 2 3)))
(list a b))
In above code snippet the compiler may detect that the literal data of a
and b
is EQUAL
. It may then have both variables point to the same literal data. Modifying it may work, but the change is visible from a
and b
.
Summary: Modification of literal data is a source of several subtle bugs. Avoid it if possible. Then you need to cons new data objects. Consing in general means the allocation of fresh, new data structures at runtime.