宏以及如何跟踪它们

Moo*_*ter 1 debugging macros trace common-lisp

trace宏对于调试非常有用。但是在任何宏上使用时它都会停止。就像我尝试执行以下操作一样:

CL-USER> (trace push)
Run Code Online (Sandbox Code Playgroud)

然后,它会给出一个错误说:

can't use encapsulation to trace anonymous function #<FUNCTION (MACRO-FUNCTION
                                                                PUSH) {100053FB9B}>
   [Condition of type SIMPLE-ERROR]
Run Code Online (Sandbox Code Playgroud)

嗯,这很明显,因为 , 的 clhs 页面trace清楚地根据函数定义了它。那么,Common Lisp 中没有任何用于跟踪宏的工具的原因是什么?
有没有其他(非常规)方法来跟踪 Common Lisp 中的宏?

Rai*_*wig 5

Common Lisp 标准只提到了函数的跟踪。在编译的实现中,宏扩展通常发生在编译时,因此通常不支持宏的跟踪。

但是一些 Common Lisp 实现可以通过 Lisp 解释器(!)跟踪宏:

CLISP 可以跟踪宏

[1]> (defmacro foo (a) a)
FOO
[2]> (trace foo)
;; Tracing macro FOO.
(FOO)
[3]> (loop for i below 4 collect (foo i))
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
1. Trace: (FOO I)
1. Trace: FOO ==> I
(0 1 2 3)
Run Code Online (Sandbox Code Playgroud)

LispWorks 是另一种支持宏跟踪的实现。

那么,Common Lisp 中没有任何用于跟踪宏的工具的原因是什么?

如前所述,这是语言标准。除了语言标准实现之外,还以各种方式提供了各种语言扩展,包括一些 Lisp 解释器 (!) 跟踪宏的能力。

如果代码已经编译,则跟踪无论如何都不会工作。拥有 Lisp 解释器会有所帮助,但实现不需要解释器。这里的 Lisp 解释器是指一个执行引擎,它以 Lisp 代码作为数据工作。