私はこれまで主にオブジェクト指向プログラミングに触れてきましたが、関数型言語を学ぶことを楽しみにしています。私の質問は:
- オブジェクト指向よりも関数型プログラミングを選ぶのはいつですか?
- 関数型プログラミングがより良い選択である典型的な問題定義は何ですか?
私はこれまで主にオブジェクト指向プログラミングに触れてきましたが、関数型言語を学ぶことを楽しみにしています。私の質問は:
回答:
オブジェクト指向よりも関数型プログラミングを選ぶのはいつですか?
別の種類のソフトウェアの進化が予想される場合:
オブジェクト指向言語は、物事に一定の操作セットがあり、コードが進化するにつれて主に新しい物事を追加する場合に適しています。これは、既存のメソッドを実装する新しいクラスを追加することで実現でき、既存のクラスはそのままになります。
関数型言語は、固定されたものがある場合に適し ています。コードが進化するにつれて、主に既存のものに新しい操作を追加します。これは、既存のデータ型で計算する新しい関数を追加することで実現でき、既存の関数はそのままになります。
進化が間違った方向に進むと、問題が発生します。
オブジェクト指向プログラムに新しい操作を追加するには、多くのクラス定義を編集して新しいメソッドを追加する必要がある場合があります。
関数型プログラムに新しい種類のものを追加するには、多くの関数定義を編集して新しいケースを追加する必要がある場合があります。
この問題は長年にわたってよく知られています。1998年、フィルワドラーはそれを「表現の問題」と呼んだ。一部の研究者は、表現の問題はミックスインなどの言語機能で対処できると考えていますが、広く受け入れられている解決策はまだ主流に達していません。
関数型プログラミングがより良い選択である典型的な問題定義は何ですか?
関数型言語は、シンボリックデータをツリー形式で操作するのに優れています。好きな例はコンパイラーで、ソース言語と中間言語がめったに変更されない(ほとんど同じもの)が、コンパイラー作成者は常に新しい翻訳とコードの改善または最適化(物事の新しい操作)を追加しています。より一般的には、コンパイルと翻訳は、関数型言語の「キラーアプリ」です。
必ずしも2つのパラダイムから選択する必要はありません。多くの機能概念を使用して、OOアーキテクチャでソフトウェアを作成できます。FPとOOPは本質的に直交しています。
C#を例にとります。ほぼOOPと言えるかもしれませんが、FPの概念や構成は多数あります。Linqを検討する場合、Linqの存在を許可する最も重要な構成要素は本質的に機能的です:ラムダ式。
別の例、F#。それは主にFPであると言うことができますが、多くのOOPの概念と構成が利用可能です。クラス、抽象クラス、インターフェースを定義し、継承を扱うことができます。コードをより明確にする場合、またはパフォーマンスを劇的に向上させる場合は、可変性を使用することもできます。
現代の言語の多くはマルチパラダイムです。
私は同じ船に乗っているので(OOPバックグラウンド、FPの学習)、私が本当に感謝しているいくつかの読みを提案します。
Jeremy Millerによる毎日の.NET開発のための関数型プログラミング。C#でのFPの多くの手法と実用的な実際の例を示す優れた記事(形式は正しくありません)。
Tomas Petricekによる実世界の関数型プログラミング。FPの概念を主に扱い、それらが何であるかを説明しようとする優れた本です。F#とC#の両方に多くの例があります。また、ペトリセクのブログは素晴らしい情報源です。
オブジェクト指向プログラミングは以下を提供します:
HaskellまたはScalaの関数型プログラミングでは、型クラスのより一般的なメカニズムを介した置換が可能です。変更可能な内部状態は推奨されないか、禁止されています。内部表現のカプセル化も実現できます。優れた比較については、HaskellとOOPを参照してください。
「関数型プログラムに新しい種類のものを追加するには、多くの関数定義を編集して新しいケースを追加する必要があるかもしれない」というノーマンの主張。関数型コードが型クラスをどれだけうまく使用しているかによって異なります。特定の抽象データ型でのパターンマッチングがコードベース全体に広がっている場合、実際にこの問題に苦しむことになりますが、それはおそらく最初から不十分な設計です。
EDITED型クラスについて議論する際の暗黙的な変換への参照を削除しました。Scalaでは、型クラスは変換ではなく暗黙のパラメーターでエンコードされますが、暗黙の変換は互換性のある型の置換を実現するもう1つの手段です。