web-dev-qa-db-ja.com

Javaで関数型プログラミングは可能ですか?

私はAmazon.com Bookstoreを閲覧していて、その本に出くわしました "Functional Programming for Java Developers"

私はいくつかの非常に基本的な関数型プログラミングを知っており、Javaで3年間プログラミングしています。

関数型プログラミングはJavaでも可能ですか?

42

「関数型プログラミング」と「可能性」の意味によって異なります。

あなたは明らかに機能的なパラダイムに従って物事を実装することができます。ただし、Java言語はそのための構文糖を提供しないので、いくつかのことはせいぜい退屈であり、他のものは非常に難解です。

同様に、オブジェクト指向コードは、Cのように非OOとして認識されている言語で非常にうまく書くことができます。

Javaライブラリ

あなたのためにすでにレッグワークを行い、難解なものを隠すことにより、これを行うのに役立つライブラリがあります:

これらを使用すると、FP対応の言語から期待されるように、より機能的なアプローチと、おそらくより馴染みのある構文とセマンティックでJavaコードを記述できます。理由は、それだけです。

JVM言語

そして明らかに、Javaの上に関数型言語を実装できます。そのため、その言語をFP言語として使用できます。これは、あなたが要求したものよりも少し高いレベルの抽象化ですが、コンテキスト内では比較的です(ただし、ここにビット、付与されます)。

たとえば、以下を確認してください。

多かれ少なかれ機能的なJVM言語

それらがあなたが望んでいるものと正確に一致しないかもしれませんが、Javaプラットフォームに移植された他の多くの言語があり、Javaのそれほど面白くない指向から解放されるかもしれません(そうです、意図されたしゃれ)の性質であり、すでにより多くの柔軟性を提供します。 JRubyJython および Rhino (-- Ruby =、 Python および JavaScript / ECMAScript )も、関数型プログラミングに興味深い可能性を提供しますが、それらは本質的には実際には関数型プログラミング言語ではありません。 JetBrainsの Kotlin は、それが関数型言語ではないことを明確に認識していますが、一部の関数型構成体をサポートしており、一見の価値もあります。

参考文献

これらの記事やビデオを読んだり見たりすることもできます。

70
haylem

あなたが言った本を読んでいます。ところでそれは本当に良いです。

はい、Javaで機能することは可能です。どの程度達成できるかはわかりませんが、多くの関数型プログラミングイディオムを実装できます。

最も重要なことの1つは、「状態を変更しない」という考え方でコーディングすることです。

たとえば、最終的なキーワードを使用して不変性を実現します。データ構造を使用する場合は、不変のデータ構造でコーディングする必要があります。 Google Guavaライブラリはすでにこれを行っています。

また、並行プログラミングについては、Akkaフレームワーク(アクターモデル)を利用できます。

JVMバイトコードは関数呼び出しプログラミング言語にとって非常に重要な機能である(少なくとも)Tail-call最適化をサポートしていないことに言及する価値があります。

11
Chiron

はい、それは間違いなく可能です。これは、チューリング完全な言語と実行環境の組み合わせで可能なことと同じです。自分が何をしているのかわかっていれば、それをうまく実行することもできます。

それがどれほど賢明かはわかりません。特に、それは特に慣用的ではないことに注意してください(つまり、非常に奇妙に見えます。通常とは異なる方法を実行し、通常のJavaに慣れている人々を混乱させる必要があります)。

あなたはいくつかの奇妙に見えるコード、例えばに終わるでしょう。新しい関数を定義するには:

Function twoStrings=new Function() {
  public Object apply(Object param1) {
    // do something to param1 and return a result
  }
}

関数型プログラミングを行うには、通常、次のものが必要です。

  • ファーストクラスの関数-Javaで簡単に作成でき、「関数」を表す抽象クラスまたはインターフェイスを定義することで、関数を1つ以上のパラメータに適用する「適用」メソッドがあります。
  • Closures-最後のフィールドに格納された閉じた値を使用して、上記の関数オブジェクトのインスタンスを作成します。これには匿名の内部クラスを使用できます。
  • 標準の高次関数のライブラリ-これはトリッキーですが、独自のbootstrapシンプルな数時間で関数型言語を作成できます。より洗練された機能が必要な場合は、Javaで構築された他の関数型ライブラリをチェックしてください。

ですから、エクササイズや興味深い趣味のプロジェクトとしても可能です。しかし、あなたは本当にJVMの利点を維持しながら深刻な関数型プログラミングを行いたい// Javaライブラリ、それからClojureは私の意見では断然あなたの最良の選択肢です。

pS Clojureのコアは実際にはJavaで記述されているため、Javaで関数型プログラミングを実行しながら、厄介な詳細をニースの新しい現代言語の構文の背後に隠している方法の非常に興味深い事例です。- ClojureソースコードはGitHubにあります 興味のある方のために。

6
mikera

Javaでは多少機能する可能性があります。そうすることは深刻な痛みを伴うです。の代わりに

myList.each { doSomething(it); }

あなたは次のようなものを持っています:

myList.each(new Function() { public void do(Object arg) { something(); }})

そして、真の関数型プログラミングが必要で、クロージャと関数をファーストクラスオブジェクトとして使用する場合は、別の言語を選択してください。 Scala、Clojure、GroovyはすべてJVMで実行され、レガシーJavaクラスと対話できます。

4
kevin cline

答えははっきりと「はい、もちろん」ですが、私の意見では、多くの関数型言語で最も重要な機能の1つは優れた型システムです。これをJava自分で管理することはできません。

関数型プログラムを作成し、それでもJVMを使い続けたい場合は、通常の容疑者ScalaおよびClojureの中で Frege を確認することをお勧めします。Fregeには構文とタイプがありますHaskellに非常に近いシステムですが、プログラムはJavaコードに直接変換され、他のJavaコードと対話できます。

3
Ingo

まあ、いろいろなことが可能です。 Cでオブジェクト指向プログラミングを行うことは可能です。それはあまり良い考えではありません。

JavaはFP用に設計されていないため、すべてを純粋なFPスタイルで実行しようとすると、問題が発生します。言語で作業するのではなく、言語と戦うことになります。言語だけでなく、すばらしい無料のJavaライブラリもすべてあります。そのため、純粋なFPを使用しないでください。FPおよびそれらをあなたのJavaコードに統合しますが、それをallに行うことはできないことを理解してください。

2
Mike Baranczak

OpenJDKチームから、最新のOpenJDK 8バイナリをダウンロードして、新しいラムダ式や、Collections APIで導入された新しい関数型イディオムなどを試してみてください。明確な機能スタイルでプログラミングできます。 Guava、FunctionalJava、LambdaJなどのJava8以前のライブラリとのJDK8コレクションの比較については、 "Functional programming in Java?" を参照してください。

0
JohanN