Does the list of properties in Common Lisp belong to some global state?

The code below has z as a local variable, but it behaves as if it were global:

 (defun foo (m) (let ((z '(stuff nil))) (push m (getf z 'stuff)) (print z))) (foo 1) (foo 2) (foo 3) 

I expect the conclusion to be

 (STUFF (1)) (STUFF (2)) (STUFF (3)) T 

but when I launch it using SBCL I see

 (STUFF (1)) (STUFF (2 1)) (STUFF (3 2 1)) T 

Why is this so? Is this behavior typical of property lists?

+5
lisp common-lisp sbcl
source share
1 answer

In foo , z bound to the literal expression '(stuff nil) . The function destructively changes z , thereby destructively changing the value of the literal. How LISP behaves in circumstances like this is implementation dependent. Some implementations will obediently change the literal meaning (as in your case). Other implementations put literals in read-only memory locations and will fail if you try to modify these literals.

To get the desired behavior, use COPY-LIST to make a copy of the literal that you can safely modify:

 (defun foo (m) (let ((z (copy-list '(stuff nil)))) (push m (getf z 'stuff)) (print z))) 
+6
source share

All Articles