', (quote-comma) 在普通的 lisp 中

', (quote-comma) in common lisp

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

例如:

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

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

你猜对了。

引用

特殊运算符 quote 定义了一个表达式,按字面意思计算其子形式。例如:

(quote (looks like a function call))

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

引用表达式有特殊语法,引号字符,因此'exp(quote exp)相同。当您不想计算符号时,通常就是这样写的。

反引号/逗号

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

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

`(format t "~s" ,exp)

...可以写成:

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

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

(list 'format t "~s" exp)

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

引用逗号

您在示例中看到的 quote/comma 组合是一个常见的习语,您希望将在宏展开时给出的参数(即代码)按字面意思放入要展开的代码中,而不对其求值。如果您通过宏扩展来测试您的宏,您可以看到结果代码:

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

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

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

 (+ 5 8) => 13

', 只能用在反引号表达式中。它们是两个不同的 reader 宏 ' 用于引用和 , 用于反引号 s 表达式中的计算。逗号只能出现在反引号表达式中。

`(a ',(+ 1 2))

以上同

`(a (QUOTE ,(+ 1 2)))

因为 'quote 的 reader 宏。

因此它具有与以下类似的效果:

(list (quote a) (list (quote quote) (+ 1 2)))

计算结果为

(A (QUOTE 3))

比较

`(a ',(+ 1 2))

与评估结果

(A (QUOTE 3))

基本上引用了(+ 1 2)的评估结果,并将其包含在列表中。