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"
).
假设我有一个像
这样的宏(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"
).