Mik*_*dor 2 lisp clisp common-lisp
我试图在LISP中使用两种形式的宏,它会评估两种形式,但总是返回表单2的结果.下面是我正在使用的代码 -
(defmacro testmac (x body) (prog2 x body))
Run Code Online (Sandbox Code Playgroud)
使用以下表单执行宏时,它正常工作并始终返回5,这是第二种形式.
(testmac (- 10 6) (/ 10 2))
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用以下表单执行宏时,它返回错误.
(testmac (print a) (print b))
Run Code Online (Sandbox Code Playgroud)
以下是我得到的错误 -
debugger invoked on a UNBOUND-VARIABLE: The variable B is unbound.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-INT:SIMPLE-EVAL-IN-LEXENV B #<NULL-LEXENV>)
Run Code Online (Sandbox Code Playgroud)
为什么我会收到此错误,如何使用宏来实现此功能?
PS我不能使用defun需要使用宏来执行(testmac(print a)(print b))
我试图在LISP中使用两种形式的宏,它评估两种形式,但总是返回形式2的结果.
这通常不是一个好主意 - 尽管它可能只是不准确的措辞.宏不应该评估代码 - 不是没有充分理由.通常宏只是转换代码.然后生成的代码决定要评估的内容.
(defmacro testmac (x body) (prog2 x body))
(testmac (- 10 6) (/ 10 2))
Run Code Online (Sandbox Code Playgroud)
因此,x在列表(- 10 6)和身体是该列表(/ 10 2).
您的宏返回第二个列表.
CL-USER 11 > (macroexpand-1 '(testmac (print a) (print b)))
(PRINT B)
Run Code Online (Sandbox Code Playgroud)
宏返回表单(print b).然后它被执行.
CL-USER 12 > (testmac (print a) (print b))
Error: The variable B is unbound.
Run Code Online (Sandbox Code Playgroud)
如果B未定义,则会出现您看到的错误.
没有魔法可言.