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

三世轮回 提交于 2019-12-06 03:36:09

问题


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)))

(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?


回答1:


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)))


来源:https://stackoverflow.com/questions/4632461/do-property-lists-in-common-lisp-refer-to-some-global-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!