这些 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 会打印此值。
我在看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 会打印此值。