JVM是否会阻止尾调用优化?

时间:2008-09-19 21:35:35

标签: java jvm scala tail-recursion

我在问题上看到了这句话:What is a good functional language on which to build a web service?

  

Scala特别不​​支持尾调用消除,除了自递归函数,这限制了你可以做的组合种类(这是JVM的一个基本限制)。

这是真的吗?如果是这样,那么创建这个基本限制的JVM是什么呢?

5 个答案:

答案 0 :(得分:74)

这篇文章:Recursion or Iteration?可能有帮助。

简而言之,由于安全模型以及始终需要堆栈跟踪的需要,在JVM中很难进行尾调用优化。理论上可以支持这些要求,但可能需要新的字节码(参见John Rose's informal proposal)。

Sun bug #4726340中还有更多讨论,其中评估(从2002年开始)结束:

  

我相信这可以做到,但这不是一项小任务。

目前,Da Vinci Machine项目正在进行一些工作。尾调用子项目的状态列为“proto 80%”;它不太可能进入Java 7,但我认为它在Java 8上有很好的机会。

答案 1 :(得分:27)

基本限制只是JVM不在其字节代码中提供尾调用,因此,构建在JVM上的语言本身没有提供尾调用的直接方法。有一些解决方法可以达到类似的效果(例如蹦床),但是它们会带来糟糕的性能,并且会混淆生成的中间代码,这会使调试器变得无用。

因此,在Sun实现JVM本身的尾调用之前,JVM不能支持任何生产质量的函数式编程语言。他们多年来一直在讨论它,但我怀疑它们是否会实现尾调用:它将非常困难,因为它们在实现这些基本功能之前过早地优化了它们,而Sun的工作主要集中在动态语言而不是函数式语言。 / p>

因此,有一个非常强烈的论点,即Scala不是一种真正的函数式编程语言:自从Scheme于30多年前首次引入以来,这些语言已将尾调用视为一项基本特性。

答案 2 :(得分:21)

Scala 2.7.x支持对最终方法和本地函数的自递归(一个函数调用自身)进行尾调用优化。

Scala 2.8也可能带有对trampoline的库支持,这是一种优化相互递归函数的技术。

有关Scala递归状态的大量信息可以在Rich Dougherty's blog中找到。

答案 3 :(得分:8)

除了在Lambda The Ultimate中链接的论文(来自上面发布的链接mmyers)之外,来自Sun的John Rose还有更多关于尾部呼叫优化的说法。

http://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm

我听说有一天它可能会在JVM上实现。在达芬奇机器上正在研究尾部呼叫支持。

http://openjdk.java.net/projects/mlvm/

答案 4 :(得分:0)

所有来源都指向JVM在尾递归的情况下无法优化,但在阅读Java performance tuning(2003,O'reilly)时,我发现作者声称他可以通过实现尾递归来实现更高的递归性能

你可以在第212页找到他的说法(搜索'尾递归'应该是第二个结果)。是什么给了什么?