web-dev-qa-db-ja.com

JVMはテールコールの最適化を防ぎますか?

私は質問でこの引用を見ました: Webサービスを構築するための優れた関数型言語は何ですか?

特にScalaは、自己再帰関数を除き、末尾呼び出しの除去をサポートしていません。自己再帰関数は、実行できる構成の種類を制限します(これはJVMの基本的な制限です)。

これは本当ですか?もしそうなら、この基本的な制限を作成するJVMについてはどうですか?

98
Jason Dagit

この投稿: 再帰または反復? が役立つ可能性があります。

つまり、セキュリティモデルと常にスタックトレースを使用できるようにする必要があるため、JVMでテールコールの最適化を行うのは困難です。これらの要件は理論的にはサポートされますが、おそらく新しいバイトコードが必要になります( John Roseの非公式の提案 を参照)。

Sun bug#472634 にも詳細な説明があります。ここでは、評価(2002年以降)が終了します。

それでもこれはできると思いますが、小さな仕事ではありません。

現在、 Da Vinci Machine プロジェクトで進行中の作業があります。テールコールサブプロジェクトのステータスは「proto 80%」としてリストされます。 Java 7になることはまずありませんが、Java 8。

74
Michael Myers

基本的な制限は、JVMがそのバイトコードで末尾呼び出しを提供しないことです。したがって、JVM上に構築された言語が末尾呼び出し自体を提供する直接的な方法はありません。同様の効果(トランポリンなど)を達成できる回避策がありますが、パフォーマンスが非常に低下し、生成された中間コードが難読化されるため、デバッガーが役に立たなくなります。

そのため、JVMは、SunがJVM自体に末尾呼び出しを実装するまで、生産品質の関数型プログラミング言語をサポートできません。彼らは何年も議論してきましたが、テールコールを実装することはないでしょう:このような基本的な機能を実装する前にVMを最適化しており、Sun関数型言語ではなく動的言語で。

したがって、Scalaは実際の関数型プログラミング言語ではありません。これらの言語は、Schemeが30年以上前に最初に導入されて以来、テールコールを不可欠な機能と見なしています。

27
Jon Harrop

Scala 2.7.xは、最終メソッドとローカル関数の自己再帰(それ自体を呼び出す関数)の末尾呼び出し最適化をサポートします。

Scala 2.8には、トランポリンのライブラリサポートも付属している可能性があります。これは、相互再帰関数を最適化する手法です。

Scala再帰の状態に関する多くの情報は Rich Doughertyのブログ にあります。

21

Lambda The Ultimateにリンクされた論文(上記のリンクmmyersから)に加えて、SunのJohn Roseには、テールコールの最適化について説明することがあります。

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

いつかJVMに実装されるかもしれないと聞いています。とりわけ、Da Vinci Machineではテールコールサポートが検討されています。

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

8
faran

すべてのソースは、末尾再帰の場合にJVMが最適化できないことを示していますが、 Javaパフォーマンスチューニング (2003、O'reilly)を読むと、テール再帰。

彼の主張は212ページで見つけることができます(「末尾再帰」を検索すると、2番目の結果になります)。何が得られますか?

0
fthinker