`progv` 中 `symbol-value` 的行为
behavior of `symbol-value` in `progv`
考虑到动态和词法绑定变量的行为,我理解以下代码中 symbol-value
的输出(动态绑定变量 a
被词法绑定变量 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)) ... )
不绑定词法变量,但隐藏了前者的值动态绑定。 Martin Buchmann 在评论中还指出,symbol-value
忽略了词法变量。
PROGV
特殊形式创建动态绑定,但不将变量声明为 特殊形式 用于封闭形式。
因此我们需要声明变量 x
的 LET
绑定是特殊的:
CL-USER 27 > (progv '(x) '(1)
(let ((x 2))
(declare (special x))
(list x (symbol-value 'x))))
(2 2)
DEFVAR
OTOH 声明它的变量是特殊的。在全球范围内,没有直接的方法可以撤消该声明。
考虑到动态和词法绑定变量的行为,我理解以下代码中 symbol-value
的输出(动态绑定变量 a
被词法绑定变量 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)) ... )
不绑定词法变量,但隐藏了前者的值动态绑定。 Martin Buchmann 在评论中还指出,symbol-value
忽略了词法变量。
PROGV
特殊形式创建动态绑定,但不将变量声明为 特殊形式 用于封闭形式。
因此我们需要声明变量 x
的 LET
绑定是特殊的:
CL-USER 27 > (progv '(x) '(1)
(let ((x 2))
(declare (special x))
(list x (symbol-value 'x))))
(2 2)
DEFVAR
OTOH 声明它的变量是特殊的。在全球范围内,没有直接的方法可以撤消该声明。