反引用 - 為巨集編寫程式碼模板

巨集返回程式碼。由於 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 也可以在巨集外部使用。