2013-06-26 2 views
2

재미있는 작은 프로젝트를하고 있는데, 디버그를 쉽게하기 위해 eval 지원을 추가했습니다. 하지만 나중에 문제가 발견되었습니다.평가 및 어휘 변수

(let ((x 1)) 
    (eval (1+ x))) 

(defun foo (x form) 
    (eval form)) 
(foo 1 '(1+ x)) 

위의 코드는 작동하지 않습니다. 누군가 이유와 방법을 설명해 주시겠습니까? 매우 감사합니다. 이 작업을 수행처럼

+0

참조 http://clhs.lisp.se/Body/f_eval.htm –

+0

디버그 *를 쉽게 * 만들기 위해 왜 'EVAL'을 추가하는지 명확하지 않습니다. 그것은 거의 의미가 없습니다. –

+0

@RainerJoswig 소프트웨어가 실행되는 동안 REPL과 유사한 기능을 제공 할 수 있습니다. –

답변

4

먼저,

(let ((x 1)) 
    (eval (1+ x))) 

하지만 (이것은 확실히 무언가를) 보일 수 있습니다, 그것은 당신이 그것을 할 의도 무엇을하고 있지 가능성이있다. eval은 정규 함수이므로 호출자가 평가 한 인수를받습니다. 효과적으로 2의 정수 값을 가진 eval을 호출합니다. 그러면의 결과 값으로 "계산"됩니다 (정수는 자체 인용이므로).

(defun foo (x form) 
    (eval form)) 

는 실패를 진단하는 것이 더 쉽습니다에서

. 런타임 어휘 바인딩은 퍼스트 클래스 객체가 아니지만 인터프리터/컴파일러가 백그라운드에서 유지 관리하는 객체입니다. 정규 함수 (예 : eval)는 호출 사이트에 정의 된 어휘 변수에 액세스 할 수 없습니다.

하나의 해결 방법 특수 변수를 사용하는 것입니다 :

(defun foo (x form) 
    (declare (special x)) 
    (eval form)) 

선언은 x 동적으로 그 범위 내에서 준수 할 것을, 당신의 혀짤배기 구현을 알려줍니다.

+0

감사합니다. 그것은 지금 잘 작동합니다. :-) –