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