嵌套反引用和`在emacs lisp中

时间:2013-06-30 20:39:34

标签: emacs elisp

短反引号和长反引号之间似乎存在一些差异。

(let ((x 123))
  (dolist (res (list `(a `(b ,x))
                     `(a (backquote (b ,x)))
                     (backquote (a (backquote (b ,x))))
                     (backquote (a `(b ,x)))))
    (print res)))

输出:

(a (\` (b (\, x))))

(a (backquote (b 123)))

(a (backquote (b 123)))

(a (\` (b (\, x))))

为什么它的行为与x不同?甚至不确定四个结果中的哪两个应该是令人惊讶的结果。

1 个答案:

答案 0 :(得分:3)

我不确定它是不是一个bug或一个功能,主要是因为我不确定elisp程序员是否被允许/良好练习使用backquote功能,或者它只是一种方便的方式定义功能。正确的输出是第一(和第四)输出。查看backquote的代码(在backquote.el中)很明显,`或backquote内的任何backquote都未正确展开。相关的代码是:

   ((eq (car s) backquote-backquote-symbol)
      (backquote-delay-process s (1+ level)))

其中backquote-backquote-symbol之前定义为'\`(quote-backslash-backtick)。有几种方法可以处理这个错误,但那一行可能是:

   ((or (eq (car s) backquote-backquote-symbol)
        (eq (car s) 'backquote))
      (backquote-delay-process s (1+ level)))

(或使用任何其他变量来指定反引号未混淆符号)。

编辑:仔细观察,还有另一个地方你必须添加该测试,但这包括报告补丁。我会看到我该怎么做。随着这种变化:

ELISP> (macroexpand-all `(a (backquote (b ,x))))
(a
 (list 'b x))
ELISP> (macroexpand-all `(a `(b ,x)))
(a
 (list 'b x))