主要问题:我认为尾调用优化 (TCO) 最重要的应用是将递归调用转换为循环(在递归调用具有特定形式的情况下)。更准确地说,当翻译成机器语言时,这通常会翻译成某种系列的跳跃。一些编译为本机代码(例如 SBCL)的 Common Lisp 和 Scheme 编译器可以识别尾递归代码并执行此转换。Clojure 和 ABCL 等基于 JVM 的 Lisps 很难做到这一点。JVM 是什么机器可以防止或使这变得困难?我不明白。JVM 显然没有循环问题。必须弄清楚如何进行 TCO 的是编译器,而不是它编译到的机器。
相关问题:Clojure可以将看似递归的代码转换为循环:如果程序员用关键字替换函数的尾调用,它就好像在执行 TCO recur
。但是,如果可以让编译器识别尾调用(例如 SBCL 和 CCL 所做的),那么为什么 Clojure 编译器不能确定它应该以处理尾调用的方式处理尾调用recur
?
(对不起——这无疑是一个常见问题解答,我确信上面的评论表明我的无知,但我没有成功找到之前的问题。)