反引號讀取宏 (read-macro)使得從模版 (templates)建構列表變得有可能。反引號普遍使用在宏定義中。一個日常的引用是鍵盤上的右引號 (apostrophe),然而一個反引號是一個左引號。(譯註: open quote 左引號,closed quote 右引號)。它稱做「反引號」是由於它看起來像是反過來的引號 (titled backwards)。post
(譯註: 反引號是鍵盤左上方數字 1 左邊那個: ` ,而引號是 enter 左邊那個 ')測試
一個反引號單獨使用時,等於普通的引號:spa
> `(a b c) (A B C)
和普通引號同樣,單一個反引號保護其參數被求值。rest
反引號的優勢是,在一個反引號表達式裏,你能夠使用 , (逗號)與 ,@ (comma-at)來重啓求值。若是你在反引號表達式裏,在某個東西前面加逗號,則它會被求值。因此咱們能夠使用反引號與逗號來建構列表模版:code
> (setf a 1 b 2) 2 > `(a is ,a and b is ,b) (A IS 1 AND B IS 2)
經過使用反引號取代調用 list ,咱們能夠寫出宏會產生出的展開式的宏定義。舉例來講 nil! 能夠定義爲:orm
(defmacro nil! (x) `(setf ,x nil))
Comma-at 與逗號類似,但將其(原本應該是列表的)參數扒開。將列表的元素插入模版來取代列表。element
> (setf lst '(a b c)) (A B C) > `(lst is ,lst) (LST IS (A B C)) > `(its elements are ,@lst) (ITS ELEMENTS ARE A B C)
Comma-at 在宏裏頗有用,舉例來講,在用剩餘參數 (rest parameters)表示代碼主體的宏。假設咱們想要一個 while 宏,只要初始測試表達式爲真,對其主體求值:it
> (let ((x 0)) (while (< x 10) (princ x) (incf x))) 0123456789 NIL
咱們能夠經過使用一個剩餘參數 (rest parameter) ,蒐集主體的表達式列表,來定義一個這樣的宏,接着使用 comma-at 來扒開這個列表放至展開式裏:test
(defmacro while (test &rest body) `(do () ((not ,test)) ,@body))