如何调试迭代程序?

How to debugg iterative procedures?

我正在使用 Dr. Racket 和 Racket 用于教育目的(学习 SICP 书)。 Dr. Racket 很棒,它有一个很棒的工具,叫做 "trace"。

使用后:

(require trace/racket)
(trace function)

可以看到递归过程中发生了什么。

但是,此功能不适用于迭代过程。 我希望我可以 "see" 我的代码在执行时发生了什么。我希望我能看到状态变量值的变化。

是否有替代工具或实践可以在迭代过程中获得此类信息?

跟踪不是调试。在 DrRacket 中,您按下 DEBUG 按钮并右键单击感兴趣部分的边缘,例如 if 确定助手中的基本情况或默认情况,然后选择 "Pause at this point"。然后每次点击 Go 时,您都可以一次看到绑定的参数。

如果你只想跟踪,你可以像这样跟踪一个助手:

(require racket/trace)
(define (reverse lst)
  (define (aux lst acc)
    (if (null? lst)
        acc
        (aux (cdr lst)
             (cons (car lst) acc))))
  (trace aux) ; tracing the helper
  (aux lst '()))

(reverse '(1 2 3 4))

>(aux '(1 2 3 4) '())
>(aux '(2 3 4) '(1))
>(aux '(3 4) '(2 1))
>(aux '(4) '(3 2 1))
>(aux '() '(4 3 2 1))
<'(4 3 2 1)
;==> (4 3 2 1)

如果您想使用命名 let 只需将其替换为 trace-let:

(define (reverse lst)
  ;; TODO: Put back to let
  (trace-let aux ((lst lst) (acc '()))
    (if (null? lst)
        acc
        (aux (cdr lst)
             (cons (car lst) acc)))))

使用调试器比必须在代码中添加行和删除行才能对其进行测试要快得多。