如何解决如何像这样进入SBCL? 使用 LispWorks跟踪和打印
我是 Common Lisp 的新手,我正在使用 SBCL、Slime 和 Emacs 来学习。
在阅读Common Lisp: A Gentle Introduction to Symbolic computation这本书时,作者提到了有助于调试并且能够做到这一点的 STEP 工具:
斜体文本是来自作者还是工具本身并不是 100% 清楚的。可能只是作者的评论。
然而,即使我不考虑斜体,我也无法生成这样的描述信息。
如果我使用只使用 SBCL 的 REPL,我会得到:
* (step (if (oddp 5) 'yes 'no))
YES
如果我在启用 Slime 的情况下在 Emacs 中使用 REPL,我会得到:
CL-USER> (step (if (oddp 5) 'yes 'no))
YES
作者说:
Common Lisp 的每个实现都提供了它自己的版本 工具;只是名称已标准化。
如果我在 Emacs/Slime 中用一个函数尝试同样的事情,我会得到更多信息:
(defun my-abs (x)
(cond ((> x 0) x)
((< x 0) (- x))
(t 0)))
在 REPL 上使用上面的定义和下面的命令:
CL-USER> (step (my-abs 10))
我明白了:
Evaluating call:
(MY-ABS 10)
With arguments:
10
[Condition of type STEP-FORM-CONDITION]
Restarts:
0: [STEP-CONTINUE] Resume normal execution
1: [STEP-OUT] Resume stepping after returning from this function
2: [STEP-NEXT] Step over call
3: [STEP-INTO] Step into call
4: [RETRY] Retry SLIME REPL evaluation request.
5: [*ABORT] Return to SLIME's top level.
--more--
Backtrace:
0: ((LAMBDA ()))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (LET ((SB-IMPL::*STEP-OUT* :MAYBE)) (UNWIND-PROTECT (SB-IMPL::WITH-STEPPING-ENABLED #))) #S(SB-KERNEL:LEXENV :FUNS NIL :VARS NIL :BLOCKS NIL :TAGS NIL :TYPE-RESTRICTIONS ..
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (STEP (MY-ABS 10)) #<NULL-LEXENV>)
3: (EVAL (STEP (MY-ABS 10)))
--more--
不幸的是,这些选项似乎都没有给我想要的东西(这可能是我的理解错误)。
我想看到类似的东西:
SLIME 似乎是一个彻底的工具。我可能遗漏了一些东西。
有没有办法使用 SLIME 或 SBCL 生成与书中描述的相同的输出?
解决方法
正如上面有人建议的那样,SBCL 在默认情况下确实优化了很多,并且默认编译。这是我为创建示例所做的工作:
- 我首先通过运行为“建议的优化”弥补了“错误的价值”
(declaim (optimize (debug 3) (space 0) (speed 0)))
- 然后,我定义了一个函数,不仅仅是一个
if
条件,因为这种东西总是内联的,不幸的是(尽管你可能会尝试(declaim (notinline ...))
,我没有。一种方法是创建一个调用另一个函数的函数,例如:
(defun foo () "hey!")
(defun bar () (foo))
- 现在,当我运行
(step (bar))
时,我会看到您在上面的问题中共享的调试器窗格,如果我现在选择选项 #3,进入 em>,我得到了相同的窗格,但正如预期的那样,现在专注于对foo
的调用。
祝你好运!
一些参考:
- 关于“单步执行”的 SBCL 手册:http://www.sbcl.org/manual/#Single-Stepping
- 关于“调试器策略控制”的 SBCL 手册:http://www.sbcl.org/manual/#Debugger-Policy-Control
看起来作者正在使用 LispWorks 的步进器。
使用 LispWorks
这是我的步进会话,使用 :s
步进当前表单及其所有子表单。
CL-USER 5 > (step (my-abs -5))
(MY-ABS -5) -> :s
-5 -> :s
-5
(COND ((> X 0) X) ((< X 0) (- X)) (T 0)) <=> (IF (> X 0) (PROGN X) (IF (< X 0) (- X) (PROGN 0)))
(IF (> X 0) (PROGN X) (IF (< X 0) (- X) (PROGN 0))) -> :s
(> X 0) -> :s
X -> :s
-5
0 -> :s
0
NIL
(IF (< X 0) (- X) (PROGN 0)) -> :s
(< X 0) -> :s
X -> :s
-5
0 -> :s
0
T
(- X) -> :s
X -> :s
-5
5
5
5
5
5
帮助在 :?
上:
:?
:s Step this form and all of its subforms (optional +ve integer arg)
:st Step this form without stepping its subforms
:si Step this form without stepping its arguments if it is a function call
:su Step up out of this form without stepping its subforms
:sr Return a value to use for this form
:sq Quit from the current stepper level
:bug-form <subject> &key <filename>
Print out a bug report form,optionally to a file.
:get <variable> <command identifier>
Get a previous command (found by its number or a symbol/subform within it) and put it in a variable.
:help Produce this list.
:his &optional <n1> <n2>
List the command history,optionally the last n1 or range n1 to n2.
:redo &optional <command identifier>
Redo a previous command,found by its number or a symbol/subform within it.
:use <new> <old> &optional <command identifier>
Do variant of a previous command,replacing old symbol/subform with new symbol/subform.
对于已编译的代码,它还有一个可视化的步进器,您可以在其中按红色按钮设置断点,查看中间变量的变化等。它看起来像这样:
LispWorks 是一个专有的实现和 IDE,有一个免费但有限的版本。我刚刚写了 a review,应该合并到 Cookbook 中。
跟踪和打印
你知道trace
吗? printv 是一个外部库,是类固醇的踪迹。它们类似于您欣赏的输出。
(defun factorial (n)
(if (plusp n)
(* n (factorial (1- n)))
1))
(trace factorial)
(factorial 2)
0: (FACTORIAL 3)
1: (FACTORIAL 2)
2: (FACTORIAL 1)
3: (FACTORIAL 0)
3: FACTORIAL returned 1
2: FACTORIAL returned 1
1: FACTORIAL returned 2
0: FACTORIAL returned 6
6
(untrace factorial)
printv
打印代码和返回值。
(printv:printv
(+ 2 3)
*print-case*
*package*
'symbol
(let* ((x 0) (y (1+ x)) (z (1+ y)))
(values x y z)))
;;; (+ 2 3) => 5
;;; *PRINT-CASE* => :UPCASE
;;; *PACKAGE* => #<PACKAGE "ISSR-TEST">
;;; 'SYMBOL => SYMBOL
;;; (LET* ((X 0) (Y (1+ X)) (Z (1+ Y)))
(VALUES X Y Z)) =>
[ [X=0] [Y=1] [Z=2] ]
;;; => 0,1,2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。