反引号,解开引号,引号,解开序列?
我正在阅读Let Over Lambda,它处理一些相当深层次的宏创作。 这很吸引人,我主要是努力跟上它。
在第4章中,Hoyte为CL-PPCRE匹配和替换函数实现读取器宏,以便您可以执行如下操作:
(#~m/(foo|bar)d+/ "Some foo99") ; matches!
(#~s/foo(d+)/bar1/, "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
东西上,为了清楚起见。 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)
所以:
在对双向反引号格式进行评估的过程中,首先处理内部反引用,结果是单独反向引用的格式。 在对内部反引用表单进行评估期间,只评估前面有两个逗号的元素。 然而,评估这些双重不加引号的元素的结果仍然(单独)不加引号,因此当评估所得到的单引号反向形式时再次评估。 为了仅在内部反引用表单中实现评估,必须插入普通报价,导致,',
。
怎么看
(let ((tmp (gensym)))
``(lambda (,tmp ,,tmp ,',tmp) ()))
评估为
`(LAMBDA (,TMP ,#:G42 #:G42) nil)
',X技巧用于屏蔽X从另一个评估。
怎么看:
(setq a 'fn)
(let ((x 'a)) ``(,,x ,',x)) ==> `(,a a) ==> (fn a)
;; ``,',X ==> `,(quote "the value of X") ==> "the value of X"
;; ``,,X ==> `,"the value of X" ==> "the value of the value of X"
链接地址: http://www.djcxy.com/p/52361.html
上一篇: Backquote, Unquote, Quote, Unquote sequence?
下一篇: Vim: dynamic syntax