阅读有关声明SPECIAL、特殊运算符LET、宏DEFVAR的文档以及在StackOverflow上针对Common Lisp动态与词法作用域的一些问题,例如this,我仍然无法理解在SBCL中评估这些表单后发生的以下行为。
;; x is a free variable
CL-USER> (defun fn ()
(print x))
; in: DEFUN FN
; (PRINT X)
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 1 WARNING condition
FN
CL-USER> (describe 'x)
COMMON-LISP-USER::X
[symbol]
; No value
CL-USER> (let ((x 'dinamic_1st_binding))
(declare (special x))
(print x)
(fn)
(let ((x 'dinamic_2nd_binding))
(declare (special x))
(print x)
(fn))
(let ((x 'lexical_1st_binding))
(print x)
(fn))
(values))
DINAMIC_1ST_BINDING
DINAMIC_1ST_BINDING
DINAMIC_2ND_BINDING
DINAMIC_2ND_BINDING
LEXICAL_1ST_BINDING
DINAMIC_1ST_BINDING
; No value
;; x is defvar'ed as a top level form
CL-USER> (defvar x 'dinamic_global_binding)
X
CL-USER> (describe 'x)
COMMON-LISP-USER::X
[symbol]
X names a special variable:
Value: DINAMIC_GLOBAL_BINDING
; No value
CL-USER> (let ((x 'dinamic_1st_binding))
(declare (special x))
(print x)
(fn)
(let ((x 'dinamic_2nd_binding))
(declare (special x))
(print x)
(fn))
(let ((x 'lexical_1st_binding))
(print x)
(fn))
(values))
DINAMIC_1ST_BINDING
DINAMIC_1ST_BINDING
DINAMIC_2ND_BINDING
DINAMIC_2ND_BINDING
LEXICAL_1ST_BINDING
LEXICAL_1ST_BINDING
; No value
为什么在变量
x
被 defvar 前,第三次调用 fn
会输出 DINAMIC_1ST_BINDING
,而在变量 x
被 defvar 后,它会输出 LEXICAL_1ST_BINDING
?