web-dev-qa-db-ja.com

Java 8の関数型を削除する理由

JDK 8 Lambdaエキスパートグループ(EG)がJavaプログラミング言語に新しい関数型を含めないことを決定した理由を理解しようとしています。

メーリングリストを調べてみると、 関数タイプの削除 についての議論があるスレッドを見つけました。

文の多くは私にはあいまいです。おそらくコンテキストが不足しているためか、場合によっては型システムの実装に関する知識が限られているためです。

ただし、このサイトで安全に作成できる質問がいくつかあります。これらの質問の意味をよりよく理解するのに役立ちます。

メーリングリストで質問できることは承知していますが、スレッドは古く、すべての決定はすでに行われているため、私は無視される可能性があります。何よりも、これらの人たちがすでに計画に遅れを取っていることがわかります。

関数型の削除をサポートし、SAM型の使用を承認するという彼の答えの中で、ブライアンゲッツ氏は次のように述べています。

具象化なし。関数型を具体化することの有用性について長いスレッドがありました。具象化しないと、関数タイプは無効になります。

私は彼が言及するスレッドを見つけることができませんでした。これで、構造関数型の導入がJavaほとんど名義型システム)で特定の複雑化を意味する可能性があることを理解できます。理解できないのは、パラメーター化されたSAM型が具体化の点でどのように異なるかです。

彼らは両方とも同じ具体化の問題を抱えていませんか?誰かが具体化の点で関数型がパラメーター化されたSAM型とどのように異なるかを理解していますか?

別のコメントでゲッツは言う:

タイピングには、名義と構造の2つの基本的なアプローチがあります。名義の同一性はその名前に基づいています。構造型のIDは、それが構成されているもの(「int、intのタプル」、「intからfloatへの関数」など)に基づいています。ほとんどの言語は、ほとんど名義型またはほとんど構造型を選択します。 「エッジ周辺」を除いて、名義型と構造型をうまく組み合わせる言語は多くありません。 Javaはほぼ完全に公称です(いくつかの例外はありますが、配列は構造型ですが、下部には常に公称要素型があります。ジェネリックには公称と構造の両方があり、これも実際、ジェネリックスに関する多くの人々の不満の原因の1つです。)構造型システム(関数型)をJavaの名目型システムに移植することは、新しい複雑さとEdgeケースを意味します。関数型の利点はこれに見合うものですか?

型システムの実装の経験がある方。彼がここで言及しているこれらの複雑さやEdgeケースの例を知っていますか?

正直なところ、Scalaのようなプログラミング言語は完全にJVMに基づいており、基盤となるプラットフォームの具体化の問題があっても、関数やタプルなどの構造型をサポートしていると考えると、これらの主張に混乱します。

誤解しないでください。SAMの型よりも関数の型の方が優れているということではありません。彼らがこの決定をした理由を理解したいだけです。

12
edalorzo

SAMのアプローチは、実際には、Scala(およびC++ 11)が匿名関数(Scalaの_=>_演算子またはC++ 11の[]()(ラムダ)構文)。

Java側で最初に回答する質問は、ラムダ文の戻りの型をintまたはbyteのような新しい特権型にするかどうかです。またはある種のオブジェクト型です。Scalaにはareプリミティブ型はありません-整数でさえクラスIntのオブジェクトです-そして関数も違いはなく、関数が取る引数の数に応じて、クラス_Function1_、_Function2_など。

C++ 11、Rubyおよびpythonには、明示的または暗黙的な方法で呼び出し可能なオブジェクトを返すラムダ式があります。返されたオブジェクトにはいくつかの標準メソッドがあります(たとえば、関数として呼び出すために使用できる_#call_など。C++ 11は、operator()をオーバーロードする_std::function_タイプを使用して、オブジェクトの呼び出しを呼び出すようにします。 method even look関数呼び出しのように、テキストで。:-)

Java=の新しい提案が厄介になるのは、構造型付けを使用して、単一のメインメソッドを持つComparatorなどの別のオブジェクトにそのようなメソッドを割り当てられるようにするためです- 別の名前。これは概念的にはある意味で不愉快ですが、doesは、結果のオブジェクトを、コールバックを表すオブジェクトを取る既存の関数に渡すことができることを意味します。コンパレータなど、_#compare_や_#callback_などの明確に定義された単一のメソッドを呼び出せることを期待します。operator()をオーバーライドするC++のトリックは、Cの前でもこの問題をうまく回避しました++ 11、そのようなすべてのコールバックオプションは同じ方法で呼び出すことができるため、STLはC++ 11ラムダをsortなどで使用できるようにするための調整を必要としませんでした。Javaは標準を使用していません過去にそのようなオブジェクトに名前を付けることは(おそらく、オペレーターのオーバーロードのようなトリックによって単一のアプローチが明らかにされなかったため)、それほど幸運ではないため、このハックにより、既存のオブジェクトの多くを変更する必要がなくなりますAPI。

6
jimwise