比方说,我有一个特殊的变种:
(defvar x 20)
然后我做到以下几点:
(let ((x 1)) (eval '(+ x 1))
其结果为2。
据CLHS,EVAL“评估了当前的动态环境和空词法环境的形式”。 所以,我希望得到21,而不是2。
我缺少的东西吗?
现在,如果我没有动态的符号Y结合,评估
(let ((y 1)) (eval '(+ y 1))
我得到的条件:“变量Y是未绑定”,这是有道理的,因为没有动态y的结合。
注:我使用SBCL 1.0.57
感谢您的帮助提前!
在你的榜样x
是special
,这意味着它在动态环境约束
y
并不特殊,所以它在词法环境约束
所以在第一时间eval
的环境中,可以这样表示:
dynamic environment: { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment: nil
符号x
被特殊所以eval
查找x
在当前的动态环境,并发现x = 1
假设它是在同一个LISP作为最后一个例子运行,你的第二个环境eval
看起来是这样的:
dynamic environment: { x : 20, ...other global variables... } -> nil
lexical environment: { y : 1 } -> nil
符号y
不是特殊那么eval
查找y
在空词法环境-而不是当前词法环境-而觉得没有什么。
这是有道理的,当你意识到,口齿不清一般被编译,并且词法环境可以优化到简单mov
在某些情况下的指令。
DEFVAR
声明其变量的特殊。 全球范围内,随处可见。 你也不能轻易删除此。
这也是你不应该使用通用名喜欢它的原因x
, i
, list
作为变量名DEFVAR
。 请确保您使用*x*
, *i*
和*list*
代替。 否则所有的变量,即使是本地的,与这些通用名声明特别。
文章来源: eval form supposed to evaluate a given form in a null lexical environment, I don't get what I expect