说我有像
这样的宏(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参数的内容不一样吗?
答案 0 :(得分:1)
您的代码运行良好,它只是没有做您认为应该做的事情。
(repeat 2 (print "Hi"))
两次计算其第二个参数,因此它打印"Hi"
两次。它还会返回"Hi"
两次,但是dolist
,因而repeat
会丢弃print
的返回值。
(repeat 2 (list 'print "hi"))
两次计算其第二个参数,因此它会创建列表(print "hi")
两次并丢弃它。要实际打印 "hi"
,您必须对其进行评估两次次(一旦生成代码 (print "hi")
第二次评估代码以打印"hi"
)。