2011-01-08 3 views
5

아래 코드는 로컬 변수로 z을 가지고, 아직 글로벌 인 것처럼 동작합니다 : SBCL 나는 그것을 실행할 때 내가하지만 출력이Common Lisp의 속성 목록이 일부 전역 상태를 참조합니까?

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

것으로 기대

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

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

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

왜 이런 경우입니까? 이 동작은 속성 목록 특유입니까?

+0

[데이터의 예기치 않은 지속성] (의 사용 가능한 복제 http://stackoverflow.com/questions :

안전하게 수정할 수있는 문자의 복사본을 만들 COPY-LIST를 사용하여 원하는 동작을 얻으려면/18790192/unexpected-persistence-of-data) –

답변

6

foo에서 z은 리터럴 표현 '(stuff nil)에 바인딩됩니다. 함수는 파괴적으로 z을 변경하여 리터럴 값을 파괴적으로 변경합니다. 이와 같은 상황에서의 LISP의 동작은 구현에 따라 다릅니다. 어떤 구현은 문자 그대로의 값을 순종적으로 바꿀 것이다. 다른 구현은 리터럴을 읽기 전용 메모리 위치에 배치하고 이러한 리터럴을 수정하려고하면 실패합니다.

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

'(let ((z (list 'stuff nil))))'와 같이'LIST'를 사용하는 것이 더 관용적 인 방법이라고 생각합니다. – Ken

관련 문제