假设我有一个特殊的var:
(defvar x 20)
Run Code Online (Sandbox Code Playgroud)
然后我做以下事情:
(let ((x 1)) (eval '(+ x 1))
Run Code Online (Sandbox Code Playgroud)
评估为2.
根据CLHS,eval"评估当前动态环境和零词汇环境中的形式".所以,我希望得到21而不是2.
我错过了什么吗?
现在,如果我没有符号y的动态绑定,则进行评估
(let ((y 1)) (eval '(+ y 1))
Run Code Online (Sandbox Code Playgroud)
我得到条件:"变量Y是未绑定的",这是有道理的,因为y没有动态绑定.
注意:我使用的是SBCL 1.0.57
提前感谢您的帮助!
在您的示例x中special,这意味着它在动态环境中绑定
y是不是特殊的,所以它是在约束词法环境
所以在第一次eval环境时可以这样表示:
dynamic environment: { x : 1 } -> { x : 20, ...other global variables... } -> nil
lexical environment: nil
Run Code Online (Sandbox Code Playgroud)
符号x的特殊如此eval查找x在当前的动态环境,并发现x = 1
假设它在最后一个例子中运行在同一个lisp中,你的第二个环境eval看起来像这样:
dynamic environment: { x : 20, ...other global variables... } -> nil
lexical environment: { y : 1 } -> nil
Run Code Online (Sandbox Code Playgroud)
符号y是不是特殊那么eval查找y在空
词法环境- 不是当前词法环境-而觉得没有什么.
当你意识到通常编译lisp时,这是有道理的,并且mov在某些情况下,词法环境可以优化为简单的指令.
DEFVAR声明其变量特殊.在全球范围内,无处不在.您也不能轻易删除它.
这也是你不应该使用通用名喜欢它的原因x,i,list作为变量名的DEFVAR.请确保您使用*x*,*i*并*list*代替.否则,所有具有这些通用名称的变量(即使是本地变量)都被声明为特殊