common-lisp - eval 形式应该在空词法环境中评估给定形式,我没有得到我期望的结果

标签 common-lisp

假设我有一个特殊的 var:

(defvar x 20)

然后我执行以下操作:
(let ((x 1)) (eval '(+ x 1))

评估为 2。

根据 CLHS,eval “在当前动态环境和空词法环境中评估形式”。所以,我希望得到 21 而不是 2。

我错过了什么吗?

现在,如果我没有符号 y 的动态绑定(bind),则评估
(let ((y 1)) (eval '(+ y 1))

我得到条件:“变量 Y 未绑定(bind)”,这是有道理的,因为 y 没有动态绑定(bind)。

注意:我使用的是 SBCL 1.0.57

提前感谢您的帮助!

最佳答案

在你的例子中xspecial这意味着它被绑定(bind)在动态环境中
y并不特殊,所以在词法环境中是绑定(bind)的

所以在第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在空
词法环境——不是当前的词法环境——并且什么也没找到。

当你意识到 lisp 通常是编译的,而词法
环境可以优化到简单的mov某些情况下的说明。

关于common-lisp - eval 形式应该在空词法环境中评估给定形式,我没有得到我期望的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11636807/

相关文章:

lisp - 如何使用任意数量的参数在 lisp 中定义结构?

lisp - ABCL 编译和原语

emacs - ASDF 在自定义目录中找不到包

sockets - Clozure Common Lisp-TCP套接字编程-发送答复

lisp - 禁用 lispworks capi :push-button-panel 上的单个按钮

common-lisp - 如何自定义SBCL REPL?

lisp - 破坏性 Lisp 函数名称中的 "N"缩写的是什么词?

lisp - 如何从 lisp 中的字符串列表创建递归嵌套的列表

lisp - "Cons"在 Lisp 中如何工作?

common-lisp - 如何在仅限 IPv6 的网络上使用 Clozure CL?