评估和词汇变量 [英] Eval and lexical variables
问题描述
我正在做一个小项目,只是为了好玩,我添加了对它的eval
支持以简化调试.但是后来我发现了一个问题:
I'm doing a small project just for fun, and I added eval
support for it to make debug easier. But later I found a problem:
(let ((x 1))
(eval (1+ x)))
(defun foo (x form)
(eval form))
(foo 1 '(1+ x))
上面的代码不起作用.有人可以解释为什么以及如何解决吗?非常感谢.
Code above won't work. Could someone please explain why and how to work it around? Thanks very much.
推荐答案
首先,
(let ((x 1))
(eval (1+ x)))
看起来确实可以工作(它确实可以做某事),可能不起作用,您打算做什么. eval
是常规函数,因此它接收由调用方评估的参数.有效地,您正在使用2
的整数值调用eval
,然后将其求值"(因为整数是自引号),结果结果为2
.
may look like it does work (it certainly does something), it is likely not doing, what you intend it to do. eval
is a regular function, so it receives its arguments evaluated by the caller. Effectively, you are calling eval
with an integer value of 2
-- which is then "evaluated" (since integers are self-quoting) to a result value of 2
.
在
(defun foo (x form)
(eval form))
更容易诊断故障.运行时词法绑定不是一流的对象,而是由后台的解释器/编译器维护的东西.常规函数(如eval
)无法访问在其调用位置定义的词法变量.
it's easier to diagnose the failure. Run-time lexical bindings are not first-class objects, but something maintained by the interpreter/compiler behind the scenes. Regular functions (like eval
) cannot access lexical variables defined at their call-sites.
一种解决方法是使用特殊变量:
One work-around would be to use special variables:
(defun foo (x form)
(declare (special x))
(eval form))
该声明告诉您的Lisp实现,x
应该在其范围内动态绑定.
The declaration tells your lisp implementation, that x
should be dynamically bound within its scope.
这篇关于评估和词汇变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!