Lisp SBCL 宏引用列表作为参数

Lisp SBCL macro quoted list as parameter

假设我有一个像

这样的宏
(defmacro repeat (times &body body)
 (let ((x (gensym)))
  `(dotimes (,x ,times)
    ,@body)))

然后我可以 运行 上 repl

CL-USER> (repeat 2 (print "Hi"))

"Hi"
"Hi"
NIL

如果我运行

CL-USER> (list 'print "Hi")
(PRINT "Hi")

所以为什么我不能 运行

CL-USER> (repeat 2 (list 'print "hi"))
NIL

反引号只是给了我一个列表,不是吗?当我不使用反引号(s 表达式列表)时,这与传递给 body 参数的内容不同吗?

您的代码工作正常,只是没有按照您的预期进行。

(repeat 2 (print "Hi")) 计算它的第二个参数两次,所以它打印两次 "Hi"。它也 returns "Hi" 两次,但是 dolist,因此 repeat 丢弃了 print 的 return 值。

(repeat 2 (list 'print "hi")) 对其第二个参数求值两次,因此它创建列表 (print "hi") 两次并丢弃它。要实际使用它 print "hi",您必须对其求值 两次 次(一旦生成 code (print "hi") 第二次评估代码打印 "hi").