我在这个问题上看到了这句话: 什么是构建 Web 服务的良好函数式语言?

Scala 尤其不支持尾部调用消除,除非在自递归函数中,这限制了您可以执行的组合类型(这是 JVM 的基本限制)。

这是真的?如果是这样,那么 JVM 的什么造成了这个基本限制呢?

有帮助吗?

解决方案

这个帖子: 递归还是迭代? 可能有帮助。

简而言之,由于安全模型以及始终需要可用的堆栈跟踪,尾调用优化很难在 JVM 中实现。理论上可以支持这些要求,但可能需要新的字节码(请参阅 约翰·罗斯的非正式提案).

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

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

目前,部分工作正在进行中 达芬奇机器 项目。尾部调用子项目的状态被列为“proto 80%”;它不太可能进入 Java 7,但我认为它在 Java 8 中很有机会。

其他提示

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

因此,除非 Sun 在 JVM 本身中实现尾调用,否则 JVM 无法支持任何生产质量的函数式编程语言。他们已经讨论了很多年,但我怀疑他们是否会实现尾部调用:这将非常困难,因为他们在实现此类基本功能之前就过早地优化了虚拟机,而 Sun 的工作主要集中在动态语言而不是函数式语言上。

因此,有一个非常有力的论点认为 Scala 不是真正的函数式编程语言:自从 30 多年前首次引入Scheme 以来,这些语言就将尾部调用视为一项基本功能。

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

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

有关 Scala 递归状态的大量信息可以在 里奇·多尔蒂的博客.

除了 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/

所有来源都指出 JVM 无法在尾递归的情况下进行优化,但在阅读后 Java 性能调优 (2003,O'reilly)我发现作者声称他可以通过实现尾递归来实现更好的递归性能。

你可以在第 212 页找到他的主张(搜索“tail recursion”应该是第二个结果)。是什么赋予了?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top