反引用 - 为宏编写代码模板
宏返回代码。由于 Lisp 中的代码由列表组成,因此可以使用常规列表操作函数来生成它。
;; A pointless macro
(defmacro echo (form)
(list 'progn
(list 'format t "Form: ~a~%" (list 'quote form))
form))
这通常很难阅读,尤其是在较长的宏中。该反引号读者宏允许一个写引用模板,通过选择性地评估元素填充。
(defmacro echo (form)
`(progn
(format t "Form: ~a~%" ',form)
,form))
(macroexpand '(echo (+ 3 4)))
;=> (PROGN (FORMAT T "Form: ~a~%" '(+ 3 4)) (+ 3 4))
这个版本看起来几乎像常规代码。逗号用于评估 FORM
; 其他一切都按原样返回。请注意,在',form
中,单引号位于逗号之外,因此将返回。
也可以使用 ,@
来拼接位置中的列表。
(defmacro echo (&rest forms)
`(progn
,@(loop for form in forms collect `(format t "Form: ~a~%" ,form))
,@forms))
(macroexpand '(echo (+ 3 4)
(print "foo")
(random 10)))
;=> (PROGN
; (FORMAT T "Form: ~a~%" (+ 3 4))
; (FORMAT T "Form: ~a~%" (PRINT "foo"))
; (FORMAT T "Form: ~a~%" (RANDOM 10))
; (+ 3 4)
; (PRINT "foo")
; (RANDOM 10))
Backquote 也可以在宏外部使用。