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))
相关文章
相关标签/搜索