考虑以下代码:
CL-USER> (defmacro sum (a b)
(+ a b))
SUM
CL-USER> (let ((alpha 3) (beta -1))
(sum alpha beta))
; in: LET ((ALPHA 3) (BETA -1))
; (SUM ALPHA BETA)
;
; caught ERROR:
; during macroexpansion of (SUM ALPHA BETA). Use *BREAK-ON-SIGNALS* to intercept.
;
; Argument X is not a NUMBER: ALPHA
; (LET ((ALPHA 3) (BETA -1))
; (SUM ALPHA BETA))
;
; caught STYLE-WARNING:
; The variable ALPHA is defined but never used.
;
; caught STYLE-WARNING:
; The variable BETA is defined but never used.
;
; compilation unit finished
; caught 1 ERROR condition
; caught 2 STYLE-WARNING conditions
; Evaluation aborted on #<SB-INT:COMPILED-PROGRAM-ERROR {10030E4223}>.
基本上有两个原因(我能想到),这导致了这段代码的失败:
1.sum
首先根据两个变量alpha
和对宏进行评估beta
,它们作为符号发送到宏中。因此,要在宏内部评估的代码是:
(+ 'alpha 'beta)
这是行不通的,因为我们不能添加两个符号。
2. 变量alpha
andbeta
是词法绑定的,因此宏的代码不能访问alpha
and的符号值beta
。
因此,重新定义sum
:
CL-USER> (defmacro sum (a b)
(+ (symbol-value a) (symbol-value b)))
WARNING: redefining COMMON-LISP-USER::SUM in DEFMACRO
SUM
在这里,宏sum
将评估提供给它的符号的值。只有在符号范围内,它才能做到这一点。因此,为了做到这一点,我们可以进行alpha
动态beta
绑定。
此外,为了检查动态绑定是否有效,我们可以创建一个函数dynamic-checker
,定义如下:
CL-USER> (defun dynamic-checker ()
(+ alpha beta))
; in: DEFUN DYNAMIC-CHECKER
; (+ ALPHA BETA)
;
; caught WARNING:
; undefined variable: ALPHA
;
; caught WARNING:
; undefined variable: BETA
;
; compilation unit finished
; Undefined variables:
; ALPHA BETA
; caught 2 WARNING conditions
DYNAMIC-CHECKER
最后,我们可以在 REPL 中评估这段代码:
CL-USER> (let ((alpha 3) (beta -1))
(declare (special alpha))
(declare (special beta))
(print (dynamic-checker))
(sum alpha beta))
这给了我们错误:
; in: LET ((ALPHA 3) (BETA -1))
; (SUM ALPHA BETA)
;
; caught ERROR:
; during macroexpansion of (SUM ALPHA BETA). Use *BREAK-ON-SIGNALS* to intercept.
;
; The variable ALPHA is unbound.
;
; compilation unit finished
; caught 1 ERROR condition
2 ; Evaluation aborted on #<SB-INT:COMPILED-PROGRAM-ERROR {1003F23AD3}>.
CL-USER>
注意2
错误代码末尾的。这是由函数返回的dynamic-checker
,它添加alpha
和beta
,即使它们不是它的参数,这证明变量alpha
和beta
可以被 的成员动态访问let
。
因此,宏sum
现在应该可以工作了,因为之前发生的两个问题都得到了解决。
但这显然不是这种情况,我错过了一些东西。
任何帮助表示赞赏。