首页 > 解决方案 > ',(引号逗号)在普通 lisp 中

问题描述

',lisp中反引号表达式的作用和用途是什么?它有名字吗?它是否记录在某个地方?它有多普遍和有用?

例如:

(defmacro test-exp (exp)
  `(format t "~&~S => ~S~%" ',exp ,exp))

我的猜测是,在这里它将exp在宏扩展时采用字面上的任何内容,并',exp用它替换。(与评估exp和替换,exp它相反)。

标签: escapingcommon-lispquotingbackquote

解决方案


你猜对了。

引用

特殊运算符定义quote了一个表达式,该表达式从字面上看是其子形式。例如:

(quote (looks like a function call))

内部形式看起来像一个函数调用,但对于 Lisp 阅读器来说,这只是一个符号列表。该表达式(quote ...)计算为该列表,而不尝试将该列表作为代码进行计算。

引用表达式有特殊语法,即引号字符,因此'exp(quote exp). 当您不想评估符号时,这通常是您编写符号的方式。

反引号/逗号

Quasiquotation 是一种仅引用表达式的一部分的方法。

反引号的作用类似于引号:不评估其中的数据,除非它们以逗号为前缀,在这种情况下,评估会重新打开。下面的表达式

`(format t "~s" ,exp)

...可以写成:

(list 'format 't '"~s" exp)

为了完整起见,我在文字之前添加了引号,否则它们会自我评估,但实际上你会编写如下相同的列表:

(list 'format t "~s" exp)

这里exp被评估,整个表单给出了一个类似于调用的列表format,其中env被替换为它的值。

引用逗号

您在示例中看到的引号/逗号组合是一个常见的习惯用法,您希望将在宏扩展时给出的参数(即代码)按字面意思放在正在扩展的代码中,而不对其进行评估。如果您通过宏扩展来测试您的宏,您可以看到生成的代码:

(macroexpand '(test-exp (+ 5 8)))

=> (FORMAT T "~&~S => ~S~%" '(+ 5 8) (+ 5 8))

文字(+ 5 8)形式被放置在一个(quote ...)表单中,使其在运行时不被评估。同时,相同的表达式按原样放在它旁边,从而在运行时对其进行评估。如果您评估结果表达式,它会打印:

 (+ 5 8) => 13

推荐阅读