9

短反引号和长反引号之间似乎存在一些区别。

(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 的行为不同?甚至不确定四个结果中的哪两个应该是令人惊讶的结果。

4

1 回答 1

3

我不确定这是一个错误还是一个功能,主要是因为我不确定是否允许 elisp 程序员/良好的做法来使用该backquote函数,或者它只是定义函数的一种方便方式。正确的输出是第一个(和第四个)输出。查看backquote(in backquote.el) 的代码,很明显,任何backquote内部的 ` 或backquote都没有正确展开。相关的代码是:

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

wherebackquote-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))
于 2013-06-30T21:37:48.770 回答