JVM 是否会阻止尾部调用优化?
我在这个问题上看到了这样的引用:什么是构建 Web 服务的良好函数式语言?
Scala 特别不支持尾调用消除,除了自递归函数之外,这限制了您可以执行的组合类型(这是 JVM 的基本限制)。
这是真的? 如果是这样,那么 JVM 的什么造成了这个基本限制呢?
I saw this quote on the question: What is a good functional language on which to build a web service?
Scala in particular doesn't support tail-call elimination except in self-recursive functions, which limits the kinds of composition you can do (this is a fundamental limitation of the JVM).
Is this true? If so, what is it about the JVM that creates this fundamental limitation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这篇文章:递归还是迭代?可能会有所帮助。
简而言之,由于安全模型以及始终需要可用的堆栈跟踪,尾调用优化很难在 JVM 中实现。 理论上可以支持这些要求,但可能需要新的字节码(请参阅 John Rose 的非正式提案)。
Sun bug #4726340 中还有更多讨论,其中评估(来自2002)结束:
目前,Da Vinci Machine 项目正在进行一些工作。 尾部调用子项目的状态被列为“proto 80%”; 它不太可能进入 Java 7,但我认为它在 Java 8 中很有机会。
This post: Recursion or Iteration? might help.
In short, tail call optimization is hard to do in the JVM because of the security model and the need to always have a stack trace available. These requirements could in theory be supported, but it would probably require a new bytecode (see John Rose's informal proposal).
There is also more discussion in Sun bug #4726340, where the evaluation (from 2002) ends:
Currently, there is some work going on in the Da Vinci Machine project. The tail call subproject's status is listed as "proto 80%"; it is unlikely to make it into Java 7, but I think it has a very good chance at Java 8.
根本限制在于 JVM 不在其字节代码中提供尾部调用,因此,构建在 JVM 上的语言没有直接的方法来提供尾部调用本身。 有一些解决方法可以实现类似的效果(例如蹦床),但它们的代价是糟糕的性能和混淆生成的中间代码,这使得调试器毫无用处。
因此,除非 Sun 在 JVM 本身中实现尾调用,否则 JVM 无法支持任何生产质量的函数式编程语言。 他们已经讨论了很多年,但我怀疑他们是否会实现尾部调用:这将非常困难,因为他们在实现此类基本功能之前就过早地优化了虚拟机,而 Sun 的工作主要集中在动态语言而不是函数式语言上。
因此,有一个非常有力的论点认为 Scala 不是真正的函数式编程语言:自从 30 多年前首次引入 Scheme 以来,这些语言就将尾部调用视为一个基本功能。
The fundamental limitation is simply that the JVM does not provide tail calls in its byte code and, consequently, there is no direct way for a language built upon the JVM to provide tail calls itself. There are workarounds that can achieve a similar effect (e.g. trampolining) but they come at the grave cost of awful performance and obfuscating the generated intermediate code which makes a debugger useless.
So the JVM cannot support any production-quality functional programming languages until Sun implement tail calls in the JVM itself. They have been discussing it for years but I doubt they will ever implement tail calls: it will be very difficult because they have prematurely optimized their VM before implementing such basic functionality, and Sun's effort is strongly focused on dynamic languages rather than functional languages.
Hence there is a very strong argument that Scala is not a real functional programming language: these languages have regarded tail calls as an essential feature since Scheme was first introduced over 30 years ago.
Scala 2.7.x 支持最终方法和本地函数的自递归(调用自身的函数)的尾部调用优化。
Scala 2.8 也可能提供对 Trampoline 的库支持,这是一种优化相互递归函数的技术。
有关 Scala 递归状态的大量信息可以在 Rich Dougherty 的博客。
Scala 2.7.x supports tail-call optimization for self-recursion (a function calling itself) of final methods and local functions.
Scala 2.8 might come with library support for trampoline too, which is a technique to optimize mutually recursive functions.
A good deal of information about the state of Scala recursion can be found in Rich Dougherty's blog.
除了 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/
In addition to the paper linked in Lambda The Ultimate (from the link mmyers posted above), John Rose from Sun has some more to say about tail call optimization.
http://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm
I have heard that it might be implemented on the JVM someday. Tail call support amongst other things are being looked at on the Da Vinci Machine.
http://openjdk.java.net/projects/mlvm/
所有来源都指出 JVM 在尾递归的情况下无法优化,但在阅读Java 性能调优 (2003, O'reilly) 我发现作者声称他可以通过实现尾递归来实现更好的递归性能。
你可以在第 212 页找到他的主张(搜索“tail recursion”应该是第二个结果)。 是什么赋予了?
All sources point to the JVM being unable to optimize in the case of tail recursion, but upon reading Java performance tuning (2003, O'reilly) I found the author claiming he can achieve greater recursion performance by implementing tail recursion.
You can find his claim on page 212 (search for 'tail recursion' it should be the second result). What gives?