我正在阅读 Let Over Lambda,它处理了一些非常深层次的宏创作。这很有趣,我主要是设法跟上它。
在第 4 章中,Hoyte 为 CL-PPCRE 匹配和替换函数实现了读取器宏,因此您可以执行以下操作:
(#~m/(foo|bar)\d+/ "Some foo99") ; matches!
(#~s/foo(\d+)/bar\1/, "Some foo99") ; "Some bar99
为了实现这一点,我们定义了一个使用双反引号的宏,因为它实际上是由一个需要引用值的包装宏扩展的(它返回一个 lambda 形式)。在准引用列表中,有一些使用以下序列,',varname
,我无法理解。初始,'
在这里做什么?
(defmacro! pcre/match-lambda-form (o!args)
"Expands to a lambda that applies CL-PPCRE:SCAN"
``(lambda (,',g!str)
(cl-ppcre:scan ,(car ,g!args)
,',g!str)))
defmacro
实际上,如果你没有读过这本书,为了清楚起见,我将它提炼成使用 just 可能会更好。str
是一个符号并且args
是一个列表:
(defmacro pcre/match-lambda-form (args)
"Expands to a lambda that applies CL-PPCRE:SCAN"
``(lambda (,',str)
(cl-ppcre:scan ,(car ,args)
,',str)))
引号基本上是双引号内部部分,以便结果可以被取消引用两次吗?有效地放入'str
扩展形式,而不仅仅是str
?
编辑 | 感谢 Terje D. 和一些在 REPL 中玩耍的人,情况大致如此:
(defvar a 42)
(equal ``(,,a) '(list 42)) ; T
(equal ``(,a) '(list a)) ; T
(equal ``(,',a) ''(42)) ; T
(equal ``(a) ''(a)) ; T (obviously)
所以:
- 双引号,表格完全展开。
- 单引号,形式不展开。
- 不带逗号,表格完全展开并引用结果。