关闭尾调用优化以在 Chez Scheme 中进行调试
Turn off tail call optimization for debugging in Chez Scheme
我正在 Chez Scheme 中调试以下程序。
(define (proc3 x3)
(printf "proc3 ~a\n" (+ 1 x3)))
(define (proc2 x2)
(printf "proc2 ~a\n" x2)
(proc3 x2))
(define (proc1 x1)
(printf "proc1 ~a\n" x1)
(proc2 x1))
(proc1 'a)
运行 这个程序会报错。
(debug)
该程序产生以下信息:
$ scheme
Chez Scheme Version 9.5
Copyright 1984-2017 Cisco Systems, Inc.
> (load "debugging.scm")
proc1 a
proc2 a
Exception in +: a is not a number
Type (debug) to enter the debugger.
> (debug)
debug> i
#<continuation in proc3> : sf
0: #<continuation in proc3>
1: #<system continuation in ksrc>
2: #<system continuation>
3: #<system continuation in dynamic-wind>
4: #<system continuation in dynamic-wind>
5: #<system continuation in $reset-protect>
6: #<system continuation in new-cafe>
#<continuation in proc3> :
请注意,堆栈帧仅包含最后一帧 proc3
,但我想显示 proc2
和 proc1
。这似乎是由于 Scheme 的 TCO(尾调用优化)阻止调试器检查精确的调用堆栈帧。
如果我把调用(proc3 x2)
和(proc2 x1)
放在尾部位置,调试器可以正常打印精确的调用堆栈帧。
(define (proc3 x3)
(printf "proc3 ~a\n" (+ 1 x3)))
(define (proc2 x2)
(printf "proc2 ~a\n" x2)
(proc3 x2)
(printf "proc2 leave\n"))
(define (proc1 x1)
(printf "proc1 ~a\n" x1)
(proc2 x1)
(printf "proc1 leave\n"))
(proc1 'a)
$ scheme
Chez Scheme Version 9.5
Copyright 1984-2017 Cisco Systems, Inc.
> (load "debugging.scm")
proc1 a
proc2 a
Exception in +: a is not a number
Type (debug) to enter the debugger.
> (debug)
debug> i
#<continuation in proc3> : sf
0: #<continuation in proc3>
1: #<continuation in proc2>
2: #<continuation in proc1>
3: #<system continuation in ksrc>
4: #<system continuation>
5: #<system continuation in dynamic-wind>
6: #<system continuation in dynamic-wind>
7: #<system continuation in $reset-protect>
8: #<system continuation in new-cafe>
#<continuation in proc3> :
Chez Scheme有没有办法暂时关闭TCO? (仅供调试)
谢谢。
这肯定是不可能的,因为方案规范强加尾递归调用成为迭代过程。
在实现中,有一个 APPLY return code
会丢弃通过尾递归进行的迭代过程的堆栈帧——解释器会 SCODE
检查 "NULL == CDR(SCODE)"
作为一个特殊的返回 APPLY
.
类型代码的条件
如果你想像你一样发生,你可以在eval中修改这个条件并重新编译方案——它将不再是方案。
如果要调试,可以套用其他方法。
我正在 Chez Scheme 中调试以下程序。
(define (proc3 x3)
(printf "proc3 ~a\n" (+ 1 x3)))
(define (proc2 x2)
(printf "proc2 ~a\n" x2)
(proc3 x2))
(define (proc1 x1)
(printf "proc1 ~a\n" x1)
(proc2 x1))
(proc1 'a)
运行 这个程序会报错。
(debug)
该程序产生以下信息:
$ scheme
Chez Scheme Version 9.5
Copyright 1984-2017 Cisco Systems, Inc.
> (load "debugging.scm")
proc1 a
proc2 a
Exception in +: a is not a number
Type (debug) to enter the debugger.
> (debug)
debug> i
#<continuation in proc3> : sf
0: #<continuation in proc3>
1: #<system continuation in ksrc>
2: #<system continuation>
3: #<system continuation in dynamic-wind>
4: #<system continuation in dynamic-wind>
5: #<system continuation in $reset-protect>
6: #<system continuation in new-cafe>
#<continuation in proc3> :
请注意,堆栈帧仅包含最后一帧 proc3
,但我想显示 proc2
和 proc1
。这似乎是由于 Scheme 的 TCO(尾调用优化)阻止调试器检查精确的调用堆栈帧。
如果我把调用(proc3 x2)
和(proc2 x1)
放在尾部位置,调试器可以正常打印精确的调用堆栈帧。
(define (proc3 x3)
(printf "proc3 ~a\n" (+ 1 x3)))
(define (proc2 x2)
(printf "proc2 ~a\n" x2)
(proc3 x2)
(printf "proc2 leave\n"))
(define (proc1 x1)
(printf "proc1 ~a\n" x1)
(proc2 x1)
(printf "proc1 leave\n"))
(proc1 'a)
$ scheme
Chez Scheme Version 9.5
Copyright 1984-2017 Cisco Systems, Inc.
> (load "debugging.scm")
proc1 a
proc2 a
Exception in +: a is not a number
Type (debug) to enter the debugger.
> (debug)
debug> i
#<continuation in proc3> : sf
0: #<continuation in proc3>
1: #<continuation in proc2>
2: #<continuation in proc1>
3: #<system continuation in ksrc>
4: #<system continuation>
5: #<system continuation in dynamic-wind>
6: #<system continuation in dynamic-wind>
7: #<system continuation in $reset-protect>
8: #<system continuation in new-cafe>
#<continuation in proc3> :
Chez Scheme有没有办法暂时关闭TCO? (仅供调试)
谢谢。
这肯定是不可能的,因为方案规范强加尾递归调用成为迭代过程。
在实现中,有一个 APPLY return code
会丢弃通过尾递归进行的迭代过程的堆栈帧——解释器会 SCODE
检查 "NULL == CDR(SCODE)"
作为一个特殊的返回 APPLY
.
如果你想像你一样发生,你可以在eval中修改这个条件并重新编译方案——它将不再是方案。
如果要调试,可以套用其他方法。