开发者

Do property lists in Common Lisp refer to some global state?

The code below has z as a local variable, yet it behaves as if it is a global:

(defun foo (m)
  (let ((z '(stuff nil)))
    (push m (getf z 'stuff))
    (print z))开发者_Python百科)

(foo 1)
(foo 2)
(foo 3)

I would expect the output to be

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

but when running it with SBCL I see

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

Why is this the case? Is this behaviour peculiar to property lists?


In foo, z is bound to the literal expression '(stuff nil). The function destructively alters z, thus destructively changing the value of the literal. How LISP behaves in circumstances like this is implementation-dependent. Some implementations will obediently alter the literal value (as in your case). Other implementations place literals in read-only memory locations and will fail if you attempt to modify those literals.

To get the desired behaviour, use COPY-LIST to make a copy of the literal that can be safely modified:

(defun foo (m)
  (let ((z (copy-list '(stuff nil))))
    (push m (getf z 'stuff))
    (print z)))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜