common-lisp - `symbol-value` 中 `progv` 的行为

标签 common-lisp dynamic-variables

考虑到动态和词法绑定(bind)变量的行为,我理解以下代码中 symbol-value 的输出(动态绑定(bind)变量 a 被词法绑定(bind)所遮蔽)变量a (该解释是错误的,请参阅下面的编辑)):

(defvar a 1)
(let ((a 2))
  (list a (symbol-value 'a)))
 ; => (2 2)

但是当使用progv创建类似的环境时,symbol-value给出了不同的结果:

(progv '(x) '(1)
  (let ((x 2))
    (list x (symbol-value 'x))))
 ; => (2 1)

为什么在第二个示例中 (symbol-value 'x) 返回 1

最终编辑伴随着接受的答案:在 Rainer Joswig 的回答中的整个评论中,我了解到 (let ((a 2)) ... ) 不绑定(bind)词法变量,但隐藏了前一个动态绑定(bind)的值。 Martin Buchmann 在评论中还指出,symbol-value 忽略了词汇变量。

最佳答案

PROGV 特殊形式创建动态绑定(bind),但不会将变量声明为封闭形式的特殊

因此我们需要将变量 xLET 绑定(bind)声明为特殊的:

CL-USER 27 > (progv '(x) '(1)
               (let ((x 2))
                 (declare (special x))
                 (list x (symbol-value 'x))))
(2 2)

DEFVAR OTOH 声明其变量是特殊的。在全局范围内,没有直接的方法可以撤消该声明。

关于common-lisp - `symbol-value` 中 `progv` 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66944937/

相关文章:

garbage-collection - 我怎样才能让 Lisp 垃圾收集器删除我的类槽中的外部 c++ 分配内存?

java - 在 Java 中为变量分配动态名称

file-upload - ColdFusion-如何检查上传文件字段是否为空-esp具有动态字段名?

json - 在 lisp 中输入/输出 json 文件

macros - SBCL 中奇怪的宏展开错误

common-lisp - 在列表中加入字符串的规范方法是什么?

javascript - 动态 JavaScript 变量

common-lisp - "constant is being redefined"与 defconstant?

javascript - 评估的 jquery 动态变量

matlab - 在第二级结构中赋值