反引号,解开引号,引号,解开序列?

我正在阅读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