我正在做一个小项目只是为了好玩,我添加了eval
支持它,使调试更容易。但后来我发现了一个问题:
(let ((x 1))
(eval (1+ x)))
(defun foo (x form)
(eval form))
(foo 1 '(1+ x))
上面的代码不起作用。有人可以解释为什么以及如何解决它?非常感谢。
答案 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
应该在其范围内动态绑定。