我有:
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" `,name `,value))
(defun opcode-call (&rest args)
(mapcar (lambda (arg)
(if (stringp arg)
(let ((var (gensym)))
(assign var arg)
var)
arg))
args))
当我编译操作码调用时,REPL输出:
assigning VAR to ARG
OPCODE-CALL
为什么要在编译时评估分配?
答案 0 :(得分:5)
宏是功能。他们通过参数获取代码并返回新代码。宏可能有副作用。
您的代码在宏扩展期间打印出一些副作用并返回NIL
(调用FORMAT
函数的结果)。
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" `,name `,value))
使用它:
CL-USER 11 > (multiple-value-list (macroexpand '(assign foo bar)))
assigning FOO to BAR ; prints as a side effect
(NIL T) ; the macro expansion returns two values NIL and T
引用这些论点是没有意义的。代码等同于:
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" name value))
它仍然会返回NIL
作为扩展,这可能不是你想要的。
如果您希望宏将表单扩展为对format
的调用,则需要将该调用作为列表返回。在这里,我们使用quasiquote
从模板构建列表,填写两个值:name
和value
。
(defmacro assign (name value)
`(format t "assigning ~A to ~A~%" ,name ,value))
也许你想引用这个名字:
(defmacro assign (name value)
`(format t "assigning ~A to ~A~%" ',name ,value))