lisp反引號

反引號 (Backquote)

反引號讀取宏 (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))
相關文章
相關標籤/搜索