常见的Lisp Double-Backquote,Unquote,Quote,Unquote序列? [英] Common Lisp Double-Backquote, Unquote, Quote, Unquote sequence?

查看:125
本文介绍了常见的Lisp Double-Backquote,Unquote,Quote,Unquote序列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Let Over Lambda,其中涉及一些相当深层次的宏创作.令人着迷,我主要是设法跟上它.

I'm reading Let Over Lambda, which deals with some pretty deeply layered macro authoring. It's fascinating and I'm mostly managing to keep up with it.

在第4章中,Hoyte为CL-PPCRE匹配和替换功能实现了读取器宏,因此您可以执行以下操作:

In Chapter 4 Hoyte implements reader macros for CL-PPCRE match and replace functions, such that you can do things like:

(#~m/(foo|bar)\d+/ "Some foo99")    ; matches!
(#~s/foo(\d+)/bar\1/, "Some foo99") ; "Some bar99

为了实现这一点,我们定义了一个使用双反引号的宏,因为它实际上是由包装器宏扩展的,该包装器宏需要带引号的值(它返回lambda形式).在准引用列表中,使用了以下序列,',varname,我无法理解.最初的,'在这里做什么?

In order to achieve this, we define a macro that uses the double-backquote, since it is actually expanded by a wrapper macro, which needs the quoted value (it returns a lambda form). Within the quasi-quoted list, there is some use of the following sequence ,',varname, which I can't get my head around. What does the initial ,' do here?

(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是列表:

Actually, it's probably better that I distill that down to something that uses just defmacro, for clarity if you haven't read the book. str is a symbol and args is a list:

(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吗?

Are the quotes basically double-quoting the inner parts, so that the result can be unquoted twice? Effectively putting 'str into the expanded form, instead of just str?

编辑|多亏了Terje D.和REPL的帮助,这基本上就是这种情况:

EDIT | Thanks to Terje D. and some playing around in the REPL, this is pretty much the situation:

(defvar a 42)

(equal ``(,,a)  '(list 42)) ; T
(equal ``(,a)   '(list a))  ; T
(equal ``(,',a) ''(42))     ; T
(equal ``(a)    ''(a))      ; T (obviously)

所以:

  • 双引号,表格已完全展开.
  • 单引号未展开.
  • 未用逗号引号,表单已完全展开,并且结果被引用.

推荐答案

在评估双反引号形式时,首先处理内部反引号,结果是单反引号形式.在内部反引号形式的评估期间,仅评估两个逗号前面的元素.但是,对这些未加双引号的元素求值的结果仍然(未)被单引号,因此,当对生成的单反引号形式进行求值时,将再次对其求值.为了仅使用内部反引号形式进行评估,必须插入普通引号,以产生,',.

During evaluation of a doubly backquoted form, the inner backquote is handled first, and the result is a singly backquoted form. During evaluation of the inner backquoted form, only elements preceeded by two commas are evaluated. However, the result of evaluating these doubly unquoted elements are still (singly) unquoted, and are thus evaluated again when the resulting singly backquoted form are evaluated. To achieve evaluation only in the inner backquoted form, an ordinary quote has to be inserted, resulting in ,',.

看看如何

(let ((tmp (gensym)))
    ``(lambda (,tmp ,,tmp ,',tmp) ()))

评估为

`(LAMBDA (,TMP ,#:G42 #:G42) nil)

这篇关于常见的Lisp Double-Backquote,Unquote,Quote,Unquote序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆