我在 Scheme 中读过一些关于尾调用优化的内容。但我不确定我是否理解尾调用的概念。如果我有这样的代码:
(define (fac n)
(if (= n 0)
1
(* n (fac (- n 1)))))
这可以优化吗,这样它就不会占用堆栈内存?
或者尾调用优化只能应用于这样的函数:
(define (factorial n)
(let fact ([i n] [acc 1])
(if (zero? i)
acc
(fact (- i 1) (* acc i)))))
最佳答案
考虑尾调用的一个有用方法是问“递归过程调用的结果必须发生什么?”
第一个函数不能进行尾部优化,因为内部调用 fac
的结果必须使用,并乘以 n
生成对 fac
的整体调用的结果.
然而,在第二种情况下,“外部”调用 fact
的结果是...内部调用 fact
的结果.无需对其进行任何其他操作,只需将后一个值直接作为函数值传回即可。这意味着不必保留其他函数上下文,因此可以简单地将其丢弃。
R5RS 标准通过使用 tail context 的概念来定义“尾调用”。 ,这基本上就是我上面所描述的。
关于scheme - Scheme中的递归函数是否总是尾调用优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5034158/