【发布时间】:2021-01-02 05:36:57
【问题描述】:
在为 MIT/GNU Scheme (rel 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 编译器/解释器针对相互尾递归进行了优化。那么,如何判断问题出在(不存在)尾递归优化或其他问题上。
- 什么是正确的相互尾递归? 我的初始代码是否符合优化条件?我的第二次参加是否符合资格?
【问题讨论】:
-
MIT 确实可以让你跟踪函数调用。
标签: recursion scheme tail-recursion mit-scheme mutual-recursion