scheme - Scheme中的递归函数是否总是尾调用优化?

标签 scheme tail-call-optimization

我在 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/

相关文章:

lisp - 尾递归函数将元素附加到列表

f# - 我如何知道一个函数在 F# 中是否是尾递归的

scheme - 这可以变成尾递归函数吗?

scheme - 在方案/ Racket 中重新定义 "define"是否有有效的用例?

algorithm - 如何在树形数据结构上实现尾递归

recursion - Rebol 尾调用优化

ocaml - OCaml 中的尾调用转换

f# - 使用“最终”工作流程时,缺少尾部调用优化是否会成为障碍?

scheme - PLT方案: Converting one of the macros in 'Casting SPELs in LISP'

function - 为什么我的Scheme Cube-Root程序中出现此错误?