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


12

JDK 8 Lambda Expert Group(EG)がJavaプログラミング言語に新しい関数タイプを含めないことにした理由を理解しようとしています。

メーリングリストを調べると、関数型の削除に関する議論のスレッドが見つかりました。

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

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

メーリングリストで質問をすることはできますが、スレッドは古く、すべての決定がすでに下されているので、私は無視される可能性があります。とりわけ、これらの人がすでに計画で遅れていることがわかります。

関数型の削除をサポートし、SAM型の使用を推奨するという彼の答えで、Brian Goetzは次のように述べています。

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

彼が言及しているスレッドが見つかりませんでした。今、私は、構造関数型の導入がJavaのほとんど名義型システムに特定の複雑さを暗示しているかもしれないことを理解できます。理解できないのは、具体化されたSAM型の具体化の違いです。

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

別のコメントで、ゲッツは次のように述べています。

タイピングには、名義型と構造型の2つの基本的なアプローチがあります。名義のアイデンティティはその名前に基づいています。構造型のアイデンティティは、それが構成されているものに基づいています(「int、intのタプル」または「intからfloatへの関数」など)。ほとんどの言語は、ほとんど名義的またはほとんど構造的です。「辺り」を除いて、名義型と構造型をうまく組み合わせた言語は多くありません。Javaはほぼ完全に名義です(いくつかの例外を除きます:配列は構造型ですが、下部には常に名義要素型があります;ジェネリックには名義型と構造型も混在しており、これは実際には多くのソースの一部ですジェネリックに関する人々の苦情の報告。)構造型システム(関数型)をJavaに移植する s名義型システムは、新しい複雑さとエッジケースを意味します。関数型の利点はこれだけの価値がありますか?

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

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

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


4
「構造型システム(関数型)をJavaの名義型システムに移植することは、新しい複雑さを意味します」 -これは、おそらく、言語を使用するためにさらに学ぶ必要があるユーザーにとっての複雑さを意味していました。何かのようにシンプルとJavaを使用して簡単にはC ++を学ぶために複雑かつ困難のようになり、そのようなものを。メーリングリストのメンバーは、おそらく1つの顕著な例であること、前に「改善の大きな波」の批判にほのめかすことができたJava 5が吸うクリントンの記事は、MyBatisのを開始
GNAT

3
「シンプルで使いやすいJavaは、複雑で学習しにくいC ++のようになります」:残念ながら、主流のプログラミング言語の問題の1つは、下位互換性を維持する必要があるため、複雑すぎる傾向があることです。だから私見(C ++とJavaの両方で長年の経験を持っている)この文に何か真実があります。Javaを凍結し、代わりに新しい言語を開発する必要があるという感覚をよく受けます。しかし、Oracleはそのようなリスクを負うことはできません。
ジョルジオ

4
@edalorzo:Clojure、Groovy、Scalaなどの言語が示したように、(1)新しい言語を定義する(2)下位互換性を損なうことなくJavaですでに記述されている豊富なライブラリとツールを使用する(3) Javaプログラマーは、Javaにとどまるか、別の言語に切り替えるか、または両方を使用するかを自由に選択できます。既存の言語を無期限に拡張するIMOは、携帯電話会社が常に新しいモデルを作成する必要があるのと同じように、顧客を維持するための戦略です。
ジョルジオ

2
JavaのSAMbdasから理解したように、理由の1つは、一部のライブラリ(コレクション)の下位互換性を維持することが問題になることです。
ペトルスキー-パドラック

回答:


6

SAMのアプローチは、実際にはScala(およびC ++ 11)が匿名関数(Scalaの=>演算子またはC ++ 11の[]()(ラムダ)構文で作成された)で行うことといくらか似ています。

Java側で最初に答える質問は、ラムダステートメントの戻り値の型を、またはなどの新しいプリミティブ型にするintbyte、何らかのオブジェクト型にするかです。Scalaで、存在しないいかなるプリミティブ型は-偶数の整数は、クラスのオブジェクトであるIntと機能は全く異なっていない、クラスのオブジェクトである- Function1Function2関数がとる引数の数に応じて、等、及び。

C ++ 11、ruby、およびpythonも同様に、明示的または暗黙的な方法で呼び出し可能なオブジェクトを返すラムダ式を持っています。返されたオブジェクトには#call、関数として呼び出すために使用できる標準メソッドがいくつかあります。たとえば、C ++ 11では、オブジェクトの呼び出しメソッドの呼び出しがテキスト形式でも関数呼び出しのように見えるようにstd::functionオーバーロードする型を使用します。 :-)operator()

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


1
皮肉なことに、ある種の「関数のようなもの」を表す無数の異なる互換性のない型がある場合、それらを構築するための実際のリテラル構文とは無関係に、標準関数型をライブラリに早期に追加することで問題を回避できました。java.util.Function2<T1, T2, R>Java 1.0にaがあった場合、Comparatorインターフェースは存在せず、代わりにこれらすべてのメソッドはを受け取りますFunction2<T1, T2, int>。(まあ、Function2TT_int<T1, T2>プリミティブなどのためにインターフェイスの全体の帯があるでしょうが、あなたは私のポイントを取得します。)
ヨルグW Mittag
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.