嵌套反引用和`在emacs lisp中

Jis*_*Yoo 9 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)))
Run Code Online (Sandbox Code Playgroud)

输出:

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

(a (backquote (b 123)))

(a (backquote (b 123)))

(a (\` (b (\, x))))
Run Code Online (Sandbox Code Playgroud)

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

Die*_*lla 3

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

   ((eq (car s) backquote-backquote-symbol)
      (backquote-delay-process s (1+ level)))
Run Code Online (Sandbox Code Playgroud)

其中backquote-backquote-symbol之前定义为“\”(引号-反斜杠-反引号)。有多种方法可以处理此错误,但该行可能是:

   ((or (eq (car s) backquote-backquote-symbol)
        (eq (car s) 'backquote))
      (backquote-delay-process s (1+ level)))
Run Code Online (Sandbox Code Playgroud)

(或使用任何其他变量来指定反引号非别名符号)。

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

ELISP> (macroexpand-all `(a (backquote (b ,x))))
(a
 (list 'b x))
ELISP> (macroexpand-all `(a `(b ,x)))
(a
 (list 'b x))
Run Code Online (Sandbox Code Playgroud)