这些 lisp-macro 写作风格之间有什么区别?

What the differences between these lisp-macro writing styles?

我在看common lisp的书,用三种写法写宏。但是它们之间有些不同。

(defmacro test_var (var)
  (list 'format 't var))

(defmacro test_var2 (var)
  `(format t ,var))

(defmacro test_var3 (var)
  '(format t)
  var)

我测试了这三个宏:

CL-USER> (test_var "ss")
ss
NIL

CL-USER> (test_var2 "ss")
ss
NIL

CL-USER> (test_var3 "ss")
ss

CL-USER>

为什么第三个"NIL"消失了?发生了什么??

仅供参考:如果我下次发现有关宏的一些有趣的东西怎么办,我怎样才能找到它如何工作的细节?

这 3 个等同。使用 macroexpand-1 查看您的呼叫扩展到的内容:

? (macroexpand-1 '(test_var "ss"))
(FORMAT T "ss")
T

? (macroexpand-1 '(test_var2 "ss"))
(FORMAT T "ss")
T

? (macroexpand-1 '(test_var3 "ss"))
"ss"
T

所以 (test_var "ss")(test_var2 "ss") 在编译时被翻译成 (format t "ss")。在执行时,对 format 的调用打印参数作为副作用,REPL 打印 NIL 这是表达式的值(即 what format)returns。

但是 (test_var3 "ss") 只是简单地转换为 "ss" 并对其进行评估。这里没有副作用,REPL 会打印此值。