Lisp SBCL宏引用列表作为参数

时间:2015-03-26 18:19:38

标签: macros common-lisp quote

说我有像

这样的宏
(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参数的内容不一样吗?

1 个答案:

答案 0 :(得分:1)

您的代码运行良好,它只是没有做您认为应该做的事情。

(repeat 2 (print "Hi"))两次计算其第二个参数,因此它打印"Hi"两次。它还会返回"Hi"两次,但是dolist,因而repeat会丢弃print的返回值。

(repeat 2 (list 'print "hi"))两次计算其第二个参数,因此它会创建列表(print "hi")两次并丢弃它。要实际打印 "hi",您必须对其进行评估两次次(一旦生成代码 (print "hi")第二次评估代码以打印"hi")。