如何解决在Scheme中的相互递归中实现尾部调用优化
在 MIT / GNU方案(相对于 9.2 )中为odd
和even
函数开发经典的练习代码时,我遇到了我的代码不会因大整数值而终止的问题。
首先,我测试了以下代码,该代码同时处理正值和负值:
(define error-message-number "Error. x must be a number")
(define odd?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #f)
((< x 0) (even? (+ x 1))) ;for negatives
(else (even? (- x 1)))))) ;if number n is odd then n - 1 is even
(define even?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #t)
((< x 0) (odd? (+ x 1))) ;for negatives
(else (odd? (- x 1)))))) ;if number n is even then n - 1 is odd
电话(assert (equal? #f (even? 100000000001)))
和(assert (equal? #t (odd? -100000000001)))
不会在我的计算机上终止,例如(assert (equal? #f (even? 1001)))
和(assert (equal? #t (odd? -1001)))
可以。
我的第一个想法是代码并未针对正确的尾部递归进行优化,而我没有一个,而是在每个函数中有两个尾部调用。
因此,我决定简化任务,只取正整数,就像这样:
(define error-message-positive "Error. x must be a nonnegative number")
(define odd-positive?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #f)
((< x 0) error-message-positive) ;for negatives
(else (even? (- x 1)))))) ;if number n is odd then n - 1 is even
(define even-positive?
(lambda (x)
(cond
((not (integer? x)) error-message-number)
((= x 0) #t)
((< x 0) error-message-positive) ;for negatives
(else (odd? (- x 1)))))) ;if number n is even then n - 1 is odd
但是此版本对于大整数都不返回。 因此,我有以下相关的问题:
- 功能。 MIT / GNU Scheme中的相互递归函数是否已完全优化?
- 诊断程序。有什么办法可以告诉方案确实由Scheme编译器/解释器针对相互尾递归进行了优化。因此,如何判断问题出在(没有)尾递归优化上,还是其他事情上。
- 什么是正确的相互尾部递归?我的初始代码是否有资格进行优化?我的第二张参赛资格吗?
解决方法
- 什么是正确的相互尾巴递归?
就像您的代码一样,它们都是两个版本。
- 诊断。
Empirical orders of growth FTW!
您的诊断可能不正确。特别是在我的机器上的Racket中,代码完成的预期时间为 40 分钟。而且它似乎确实在整体内存中运行。
是的,即使在恒定的空间中运行,它仍然需要时间来保持参数大小的线性关系。我怎么知道?我只是用时钟墙时间来测量它,的确确实是线性的,即 n 1 幂定律。约。 (即,无论是1.02还是0.97,它仍然指示线性增长率。这很重要。)
另请参阅:
- 功能。 MIT / GNU方案中的相互递归函数是否已完全优化?
必须这样,因为尾部调用优化在语言规范中。而且TCO不仅是尾部递归,据我了解,即使下一个调用的决定是动态的(更不用说是静态的,在您的情况下在代码中也很明显),当一个尾部调用时,它仍然必须在恒定的堆栈空间中运行最终导致再次进入相同的功能。尾部调用是尾部调用,无论调用什么,都必须对其进行优化。我目前没有官方报价。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。