【发布时间】:2013-10-28 01:03:29
【问题描述】:
主要问题:我认为尾调用优化 (TCO) 最重要的应用是将递归调用转换为循环(在递归调用具有特定形式的情况下)。更准确地说,当翻译成机器语言时,这通常会翻译成某种系列的跳跃。一些编译为本机代码(例如 SBCL)的 Common Lisp 和 Scheme 编译器可以识别尾递归代码并执行此翻译。 Clojure 和 ABCL 等基于 JVM 的 Lisps 很难做到这一点。 JVM 是什么机器可以防止或使这变得困难?我不明白。 JVM 显然没有循环问题。必须弄清楚如何进行 TCO 的是编译器,而不是它编译到的机器。
相关问题:Clojure 可以将看似递归的代码转换为循环:如果程序员用关键字recur 替换函数的尾调用,它就好像在执行TCO。但是,如果有可能让编译器识别尾调用(例如 SBCL 和 CCL 所做的),那么为什么 Clojure 编译器不能确定它应该以处理 recur 的方式处理尾调用?
(对不起——这无疑是一个FAQ,我确信上面的评论表明我的无知,但我没有成功找到之前的问题。)
【问题讨论】:
-
关于 Rich Hickey 对该主题的评论,请看:groups.google.com/d/msg/clojure/4bSdsbperNE/tXdcmbiv4g0J
-
谢谢@Jared314。该线程的其余部分也很有帮助。我应该搜索一下 Google 群组。
-
TCO 适用于所有尾调用,而不仅仅是递归调用;它不适用于所有递归调用,仅适用于尾调用。如果您要编辑您的第一句话可能会很好,这样它就不会传播对 TCO 的误解。
-
好的,好点@Rörd。我已经编辑了第一句话。
标签: clojure jvm lisp jvm-languages abcl