debugging - 如何单步执行一些 Common Lisp 代码,检查表单的返回值?

标签 debugging emacs common-lisp

也许这有点菜鸟,但我在这之后失去了理智。我非常惊讶地发现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 吗?

谢谢!

最佳答案

Common Lisp 是一种语言规范,而不是一种实现。因此,诸如“CL 的步进器”或“CL 的调试器”之类的表达式属于类别错误:语言没有步进器或调试器,但实现有。语言规范提供了一个接口(interface),step ,这样的事情可能会被调用,但是说

step implements a debugging paradigm wherein the programmer is allowed to step through the evaluation of a form. The specific nature of the interaction, including which I/O streams are used and whether the stepping has lexical or dynamic scope, is implementation-defined.

因此,您的问题的答案是不,“CL 的调试器”无法执行此操作,因为“CL 的调试器”不存在。

该语言的实现可能会为此提供或多或少的支持。例如,我知道 LispWorks例如,确实如此。我不知道其他实现是否如此。 CL 作为一种语言也具有足够的反射性,可以编写可移植步进器:sly-stepper可能是这样的事情,但我不确定。


以下是使用 LW 非 IDE 步进器的示例:

CL-USER 7 > (step (let ((x 0)) (/ (sin x) x)))
(let ((x 0)) (/ (sin x) x)) -> :su

Error: Division-by-zero caused by / of (0.0 0.0).
  1 (continue) Return a value to use.
  2 Supply new arguments to use.
  3 (abort) Return to debug level 1.
  4 Return to stepper level 1.
  5 Quit from stepper.
  6 Return to debug level 0.
  7 Restart top-level loop.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.

CL-USER 9 : 2 > :a
(let ((x 0)) (/ (sin x) x)) -> :sr 0.0
0.0 
0.0

CL-USER 8 > (step (let ((x 0)) (/ (sin x) x)))
(let ((x 0)) (/ (sin x) x)) -> :s 2
   0
   0 
   (/ (sin x) x)
      (sin x) -> :si
      0.0 
      x -> :sr 1
      1 
   0.0 
0.0 
0.0

在第一次交互中,我让它运行,直到出现错误,从中中止回到步进器,然后告诉步进器返回零。在第二步中,我单步执行,直到它即将计算 x ,然后告诉它结果是 1 ,导致它返回零。

上面的非 IDE 步进器已记录 here & IDE 步进器是 here .

关于debugging - 如何单步执行一些 Common Lisp 代码,检查表单的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76231452/

相关文章:

lisp - 对 project euler 4 的 lisp 程序的反馈

lisp - 如何让 Lisp 忘记以前导出的符号?

lisp - Eager-Future2 库 :Parallel Programming in Lisp

ruby - 线程安全 : Capturing the output of $stdout

c - printf 语句打印前一个 printf 语句

ios - 调试器(或日志)中类似 NSDictionary 的 pretty-print

emacs - 使用文本用户界面的 IDE(如 ncurses)

python - 不断收到 ValueError : not enough values to unpack (expected 2, 得到 1)

emacs - css 的 html 缩进,emacs 中的 html

c++ - ctags c++ 查找函数的第一个实例,无论类如何