2013-06-26 192 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是一個常規函數,因此它接收調用者評估的參數。實際上,您打電話給eval的整數值爲2 - 然後「評估」(因爲整數是自引用的),結果值爲2

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

它更容易診斷故障。運行時詞法綁定不是一流的對象,而是幕後的解釋器/編譯器維護的東西。常規功能(如eval)無法訪問在其呼叫站點定義的詞彙變量。

一個變通方法是使用特殊的變量:

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

的聲明告訴你的Lisp實現,即x應在其範圍內進行動態綁定。

+0

謝謝。它現在運作良好。 :-) –