2013-06-26 55 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

谢谢。它现在运作良好。 :-) –