Eval和词汇变量

时间:2013-06-26 06:03:26

标签: lisp eval common-lisp

我正在做一个小项目只是为了好玩,我添加了eval支持它,使调试更容易。但后来我发现了一个问题:

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

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

上面的代码不起作用。有人可以解释为什么以及如何解决它?非常感谢。

1 个答案:

答案 0 :(得分:5)

首先,虽然

(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应该在其范围内动态绑定。