你试图用你的宏做的是扩展一个文字列表。
不评估宏参数。所以,print-lst 实际上是接收符号 lst,而不是绑定到变量的列表。
您要么知道这一点并给print-lst 一个文字列表,要么您可以生成评估宏参数的代码:
(defmacro print-lst (lst)
(let ((item (gensym)))
;; Macros usually make sure that expanded arguments are
;; evaluated only once and in left-to-right order.
;;
;; In this case, we only have one argument and we only evaluate it once.
`(dolist (,item ,lst)
(print ,item))))
虽然这显然不是一个很好的宏示例,但它最好是一个函数:
(defun print-lst (lst)
(dolist (item lst)
(print item)))
如果你想内联调用print-lst,你可以查阅你的实现文档,看看它是否关注(declaim (inline print-lst))。
另一种选择是使用编译器宏作为函数的补充,以内联调用,其中参数的评估是编译时的已知值,但再次查看您的实现是否关注编译器宏:
(define-compiler-macro print-lst (&whole form lst &environment env)
(declare (ignorable env))
;; Some implementations have an eval function that takes an environment.
;; Since that's not standard Common Lisp, we don't use it in constantp.
(if (constantp lst)
`(progn
,@(mapcar #'(lambda (item)
`(print ,item))
(eval lst)))
;; Return the original form to state you didn't transform code.
form))