假设我有一个特殊的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
提前感谢您的帮助!
答案 0 :(得分:7)
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
在 null 中查找y
词汇环境 - 不当前的词汇环境 - 什么也没发现。
mov
指令。
答案 1 :(得分:5)
DEFVAR
声明其变量特殊。在全球范围内,无处不在。你也不能轻易删除它。
这也是你永远不应该使用x
,i
,list
等常用名称作为DEFVAR
的变量名称的原因。请确保使用*x*
,*i*
和*list*
代替。否则,具有这些通用名称的所有变量(甚至是本地变量)都被声明为特殊。