也许这是菜鸟,但我失去了我的头脑后,这一点。我非常惊讶地发现CL的stepper并不显示各种形式的返回值。我的意思是,调试器可以检查帧,REPL允许手动检查变量,但例如在以下代码中
(defun fact (n)
(if (<= n 0)
1
(* n (fact (- n 1)))))
(fact 5)
我不能指示调试器说“嘿,我刚刚跳过了表单(<= n 0)
,它返回了nil
,然后我又跳过了(- n 1)
,它返回了值4
”。这可以在Emacs-lisp和Clojure中完成(我使用Emacs,但它不是我感兴趣的接口)。我知道存在(step)
的形式,但它依赖于实现,并且我在SBCL和CMU上都看到它并没有实现我的意思。所以我的问题是,**CL的调试器可以做到这一点(步进+打印值刚刚评估)?**如果是,是否只有一个实现?你能提供MWE吗?
谢谢!
1条答案
按热度按时间e5nqia271#
Common Lisp是一种语言规范,而不是实现。因此,像'CL's stepper'或'CL's debugger'这样的表达式是类别错误:语言没有步进器或调试器,实现有。语言规范提供了一个接口
step
,通过它可以调用这样的东西,但是说step
实现了一种调试范例,其中允许程序员逐步完成表单的评估。交互的特定性质(包括使用哪些I/O流以及单步执行是否具有词法或动态范围)是由实现定义的。因此,您的问题的答案是否定的,“CL的调试器”不能这样做,因为“CL的调试器”不存在。
语言的 * 实现 * 可能会或多或少地对此提供支持。例如,我知道LispWorks是这样的。我不知道其他实现是否会这样做。CL作为一种语言也足够反射,可以编写一个便携式步进器:sly-stepper可能是这样的,但我不确定。
以下是LW非IDE步进器的使用示例:
在第一次交互中,我让它运行,直到它得到错误,从那里中止回到步进器,然后告诉步进器返回零。在第二个例子中,我逐步执行,直到它要计算
x
,然后告诉它计算的结果是1
,导致它返回零。上面的非IDE步进器在这里记录& IDE步进器在这里。