関数型プログラミングを使用して、完全なエンタープライズアプリケーションを開発できますか?


19

関数型プログラミング(FP)を学び始めたばかりです。私はすべてがオブジェクトであり、それらのほとんどが可変であるOOPの世界から来ています。関数には副作用がないという概念をまとめるのに苦労しています。

何かが可変ではない場合、従業員や個人などの一般的なオブジェクトはFPでどのように表されますか。

FPを使用して本格的なエンタープライズアプリケーションを作成できますか?


5
なぜ従業員の代表は可変でなければならないのですか?おそらく状態がありますが、それは別の質問です。

1
可変データは、物を表すために使用されます。対照的に、不変データは特定の時点で何かの値を持ちます(ただし、これは唯一のユースケースではありません)。同じものを表す2つの可変オブジェクトがあるバグがすべてある場合、物を表すためにオブジェクトを使用すると故障する可能性があることを知っています。
dan_waterworth

2
関数型プログラミングに副作用があります。そうしないと、何も印刷できなくなります。

1
@ThorbjørnRavn Andersen:命令型(手続き型、オブジェクト指向)プログラミングでは、外部世界(IO)との通信とプログラム内のデータ変換の計算の両方に副作用を使用します。FPでは、2つの世界を明確に分離します。IOにのみ副作用を使用します(通常、IOのないプログラムは無用です)が、純粋な関数を使用して内部データ変換を計算します。副作用は完全に回避することはできませんが、それらは局所的ではないため、推論するのがより困難であるため、できるだけ使用を制限することをお勧めします。
ジョルジオ

「人物」オブジェクトのようなものは、可変である必要はありません。代わりに、ほぼ同じ(ただしわずかに異なる)まったく新しい「人物」オブジェクトを作成します。どこかに「人」オブジェクトへの参照があり、古いコピーではなく新しいコピーを参照するように変更します。もちろん、その参照は何らかのコレクション内にある可能性があるため、ほぼ同じコレクションのコピーを作成します。古いコレクションを新しいコレクションに交換できるように、コレクションへの参照がどこかにある必要があります!
ブレンダン

回答:


17

質問は、「企業でFPを使用できますか?」ではありませんか?しかし、エンタープライズでFPを使用する必要がありますか?

もちろんできます。あらゆる種類のプログラミング言語を使用して、あらゆる種類のアプリケーションを開発できます。そのため、「Turing complete」と呼ばれています。

次に、「エンタープライズで使用する必要がありますか?」という質問に答えます。それはあなたまたはあなたの雇用主次第です。FPはある種のアプリケーションで本当に役立つことができます。実際、かなり多く使用されています:Haskell in the industry

今、あなたは「だからなぜもっと使われないの?」と尋ねるかもしれません。主に、他のImperative / OO言語がより一般的であり、企業はJavaまたはC ++に慣れているため、より「エキゾチックな」言語への変更を拒否しているためです。


7
You can develop any kind of application with any kind of programming languageこれは非常に弱い議論です。チューリングターピットに注意してください
...-ヤニス

5
@YannisRizos彼は問題のすべての接線を探索するのではなく、具体的な答えのために一般化していたと思います。
ジョニーロッテン

2
@YannisRizosがし!=たいことができます

1
特定の種類のエンタープライズソリューションでは、言語がチューリング完全にならないように
思える

2
言語に関して言えば、それはあなたの雇用主次第ではなく、技術的な観点から見た最善のものを推進するのはエンジニア自身次第だと私は主張します。
shmish111

11

私は数年前にFP言語について学び始めました(Haskell、Scala、Scheme)、そして私は専門家ではありませんが、C ++やJava以上の特定のタスクで私が非常に生産的になることがわかりました。

IMO、FP言語の長所のいくつかは次のとおりです。

  • それらは非常に簡潔になる傾向がありますが、明確なセマンティクスを保持します。
  • 宣言型のスタイルを使用でき、実装の詳細について深く考える必要はありません。
  • Haskellのようなリッチタイプシステムは、多くの論理エラーを非常に早期に(コンパイル時に)キャッチできます。私の知る限り(実際はそれほどではありません)、SMLとOcamlには同様の利点があります。

これまで、FPパラダイムへの切り替えは非常にエキサイティングであり、十分な時間を費やせばそれほど難しくないことがわかりました。(しかし、CまたはC ++の学習にどれくらいの時間を費やしましたか?

したがって、技術的な観点からは、関数型プログラミング言語を使用して完全なエンタープライズアプリケーションを開発することは完全に理にかなっていると思います。

残念ながら、このパラダイムは主流ではありません。ほとんどの企業は十分にテストされたテクノロジーのみを採用する傾向があるため、実際に機能すること、開発者、ツール、ライブラリ、フレームワークが十分にあることを示す十分な証拠が得られるまで、FPから遠ざかります。したがって、FPプログラミングをフルタイムで実行できる仕事を今すぐ見つけるのは(はるかに)より困難です。

マルチコアプロセッサの使用が増え、FP言語への投資が促進されれば、現在の状況は変わるかもしれません。FP言語は、並行ソフトウェアを書くのに非常に強いようです。

また、プログラマーが完全なパラダイムスイッチを必要とせずにFPを使用できるように、FP機能をC#、C ++などの非機能的な主流言語に導入する傾向があります。たぶん、10年後には、これらの言語が十分なFP機能をカバーし、純粋に機能的な言語への切り替えがはるかに容易になるでしょう。


10

必ずしも最良のアイデアだとは思いません。しかし、それは特定のアプリケーションの性質に依存します。

Eric Evansの著書であるDomain-Driven Designで説明されているように、問題を解決するのに役立つ手近な問題を表すドメインモデルを作成する必要があると私は信じています。Evansは、特定の問題に対応するプログラミング言語を見つけることを提案しています。たとえば、Fortranは数学的な問題を解決する方法として言及しています。または、目前の問題に特化したドメイン固有の言語を作成することもできます。

適切なドメインモデルの作成に成功すると、プレゼンテーションコードがドメインレイヤーの上にある薄いシェルになることがわかります。

現在、エンタープライズアプリケーションの問題は、このタイプのアプリケーション(エンタープライズアプリケーションについて一般化できる場合)では、多くの場合、アイデンティティが重要なエンティティの状態を変更し、変更したエンティティをデータベースに永続化することです。この非常に一般化されたタイプの問題は、機能モデルよりもオブジェクト指向モデルを使用することにより、はるかによく解決されます。

これは、機能的なパラダイムでは解決できないエンタープライズアプリケーションの領域があるという意味ではありません。たとえば、銀行業務アプリケーションのリスク分析モジュール、または出荷アプリケーションのルート計画モジュール。また、一部のエンタープライズアプリケーションは、機能的なパラダイムを使用して完全に実装できます。

しかし、一般に、オブジェクト指向のパラダイムにより、大部分のエンタープライズアプリケーションにとってより有用なドメインモデルを作成できると思います。

編集

いくつかの賛成により、この答えに注意が向けられました-それを書いて以来、私はFPについてより多くのことを学びました-そして私は自分の答えにもう同意するかどうかは完全にはわかりません。一部の関数型言語は、ユースケースを非常にうまく説明できます。しかし、あなたは完全に異なるマインドセットを学ぶ必要があります。


2
+1:非常に良い刺激的な答え。FPに関する知識が限られているため、これが正しいかどうかはわかりませんが、永続オブジェクトはモナドまたは一意のタイプ(クリーンで)を使用してモデル化できると思います:この方法で値がアイデンティティを取得し、プログラムに渡される可能性がありますさまざまな機能によって変換されます。しかし、これを裏付けるにはFPの専門家の意見が本当に必要です。
ジョルジオ

3

はい、できます。Googleを少し試してみると、純粋な関数型言語でコーディングされた実際のソフトウェアが見つかります。

ビジネスオブジェクトに関する質問については、実際の問題は不変性にあると思います。その場合、命令型言語を使用している場合は、変更するたびに新しい「Person」を返すことを考慮してください。

この手法は、命令型言語を使用して実装することもできます!


3

オブジェクト指向プログラミング(OOP)のような関数プログラミング(FP)はパラダイムです。これらは、プログラミングの問題に対するさまざまなパターンまたはアプローチを表しています。これらの異なるアプローチは、スケーラブルで保守可能で拡張可能なソフトウェアを作成する能力を除去しません。それは、すべての問題タイプでアプローチが同等であると言うことではありません。そうではありません。特定の問題は、特定のパラダイムにより良く(または悪く)整列します。たとえば、FPは、副作用を伴う操作の従属シーケンスを持つプログラムの最初の選択肢ではありません。ただし、そのようなプログラムは作成可能であり、すでに作成されており、適切に作成されています。


3

はい、FPはエンタープライズアプリケーションで使用できます。Clojureは、エンタープライズで成功を収めているFP言語の一例です。http//cognitect.com/clojure#successstories

状態を表現することはFPの課題になる可能性があり、FPに合わせてパラダイムを変更することは少し気が散ることがあります。一部のFP言語は、副作用と可変状態を完全に禁止しています。Clojureは両方を許可しますが、これらのパラダイムを阻止または分離します。

要するに、状態表現はオブジェクト指向に非常に似ているかもしれません。状態の変更は非常に異なります。そのため、たとえば、FP状態ではリストとマップで表すことができます。従業員のリストは次のようになります。

[[name: "James Brown" address: "Barnwell, SC"]
 [name: "Elvis Presley" address: "Tupelo, MS"]]

FPで状態の変更を処理する方法は2つあります。1つは、関数型リアクティブプログラミングのようなものです。このパラダイムでは、すべての状態は最高レベルでのみ処理されます。たとえば、アプリケーションのHTMLビューには、ビュー内に状態があります(人の名前、住所など)。「名前の更新」をクリックすると、実際に名前を変更することを除いて、名前の更新に関するすべてのことを処理する関数が呼び出されます。これは奇妙に聞こえるかもしれませんが...私に耐えてください。変更された名前は関数によって返され、ビュー(または永続データストアなど)に新しい名前が表示されます。または、代わりに、更新された名前を持つ新しい構造全体が返されます。それで、関数は何をしますか?名前を検証し、有効な場合は新しい名前を返し、有効でない場合はエラーを返します。場合によっては、新しいビューまたはナビゲーションリンクをたどることができます。名前の変更よりも複雑な場合は、さらに多くのことが行われます。

そのため、FRPの場合、関数によって返されるオブジェクトは新しい状態であり、ビューまたは高レベルのものに直接与えることができます。場合によっては、FRPは状態全体を取得して関数に渡し、状態全体を戻します。

このパラダイムでは、コンテナまたはフレームワークは、ディスプレイ、データベース、または新しい状態からの更新が必要なものの更新を処理する必要があります。したがって、画面上にアプリケーションを描画するフレームワークを想像できます。ユーザーが何かをクリックすると、関数が呼び出され、新しい状態が返されます。フレームワークは、すべてを再描画するか、ディスプレイの一部をインテリジェントに再描画することにより、画面を更新します。http://blog.getprismatic.com/om-sweet-om-high-functional-frontend-engineering-with-clojurescript-and-react/を参照してください

Clojureは、私が遭遇した2番目のパラダイムを使用します。これは、状態の変化を分離することですが、必ずしも最高レベルに制限するわけではありません。Clojureでは、アトム、エージェント、またはリファレンスによって、すべての可変状態が(状態にJavaオブジェクトを使用している場合を除き)「保持」されている必要があります。これが機能する方法は、atom / agent / refによって保持されているか、指し示されているか、または参照されている(ただし、呼び出したい)オブジェクトは不変ですが、atom / agent / refは新しいオブジェクトを指すように変更できます。この場合、atom / agent / refで「このようなことを行い、atom / agent / refを新しいオブジェクトに再割り当てすることでオブジェクトを更新する」という特別なメソッドを使用します。

なぜこれがあなたに尋ねるのに有益なのですか?これらのClojureコンストラクトによって参照される不変オブジェクトは、何かを行う関数に渡される可能性があり、その関数の実行中にオブジェクトへの参照は変更されないことが保証されているためです。つまり、atom / agent / refは関数に渡されませんが、それらが指す不変オブジェクトは渡されます。Atom、Agent、およびrefには、安全で言語の一部である方法で更新と並行性を処理する特別なプロパティがあります。http://clojure.org/stateをご覧ください

これがお役に立てば幸いです。Clojureの状態とFRPについてさらに読んで、従業員と個人がFPでどのように表現されるかについて理解を深めることをお勧めします。しかし、実際の表現はオブジェクト指向プログラミングに似ています...実際に異なるのは可変性です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.