13

假设我有一个特殊的 var:

(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

提前感谢您的帮助!

4

2 回答 2

8

在您的示例x中是special这意味着它绑定在动态环境中

y并不特殊,所以在词法环境中是绑定的


所以在第一次的时候,eval环境可以这样表示:

dynamic environment:  { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment:  nil

该符号x很特殊,因此在当前动态环境中查找并eval找到xx = 1


假设它在与上一个示例相同的 lisp 中运行,您的第二个环境eval如下所示:

dynamic environment: { x : 20,  ...other global variables... } -> nil
lexical environment: { y :  1 } -> nil

该符号y并不特殊,因此在 词法环境中查找 -而不是当前的词法环境 - 并没有找到任何东西。evaly

当您意识到 lisp 通常是编译的,并且mov在某些情况下可以将词法环境优化为简单的指令时,这是有道理的。

于 2012-07-24T19:06:06.247 回答
6

DEFVAR声明它的变量是特殊的。全球,无处不在。您也不能轻易删除它。

这也是你永远不应该使用常见名称(如x, i, )list作为DEFVAR. 确保使用*x*,*i**list*代替。否则,所有具有这些通用名称的变量,甚至是局部变量,都被声明为特殊的。

于 2012-07-24T19:27:33.090 回答