我正在阅读“让我过去”,其中涉及一些非常深层的宏创作。它很吸引人,我主要是设法跟上它。
在第4章中,Hoyte实现了用于Chapter匹配和替换函数的读取器宏,您可以这样做:
(#~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的东西。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)所以:
发布于 2013-07-03 09:09:16
在评估双后引号形式时,首先处理内部回引号,结果是单后引号形式。在计算内部反引号形式时,只计算两个逗号前面的元素。然而,评估这些双重未引用元素的结果仍然是(单)未引用的,因此,当计算结果的单后引号形式时,将再次进行评估。要实现仅在内部回引形式的评估,必须插入一个普通的引号,从而导致,',。
了解如何
(let ((tmp (gensym)))
``(lambda (,tmp ,,tmp ,',tmp) ()))评估为
`(LAMBDA (,TMP ,#:G42 #:G42) nil)发布于 2013-12-02 14:18:50
“,',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"https://stackoverflow.com/questions/17429521
复制相似问题