web-dev-qa-db-ja.com

関数型プログラミングとオブジェクト指向プログラミング

私はこれまで主にOOプログラミングに触れてきましたが、関数型言語を学ぶのを楽しみにしています。私の質問は:

  • オブジェクト指向よりも関数型プログラミングを選ぶのはいつですか。
  • 関数型プログラミングがより良い選択である典型的な問題定義は何ですか?
736
Olivier Lalonde

オブジェクト指向よりも関数型プログラミングを選ぶのはいつですか。

別の種類のソフトウェアの進化が予想される場合

  • オブジェクト指向言語は、 操作 on もの の固定セットがある場合に適しており、コードが進化するにつれて、主に新しいものが追加されます。これは、既存のメソッドを実装する新しいクラスを追加することで達成でき、既存のクラスはそのままにします。

  • 関数型言語は、固定セットの things がある場合に適しており、コードが進化するにつれて、主に既存のものに新しい operations を追加します。これは、既存のデータ型を使って計算する新しい関数を追加することで実現でき、既存の関数はそのままにしておきます。

進化が間違った方向に進むとき、あなたは問題を抱えています:

  • オブジェクト指向プログラムに新しい操作を追加するには、新しいメソッドを追加するために多くのクラス定義を編集する必要があります。

  • 機能プログラムに新しい種類のものを追加するには、新しいケースを追加するために多くの関数定義を編集する必要があります。

この問題は長年にわたってよく知られています。 1998年に Phil Wadlerはそれを "表現問題"と呼んだ 。式の問題はmixinのような言語機能で解決できると考える研究者もいますが、広く受け入れられている解決策はまだ主流になっていません。

関数型プログラミングがより良い選択である典型的な問題定義は何ですか?

関数型言語は、ツリー形式でのシンボリックデータの操作に優れています。最も良い例は、ソース言語と中間言語がめったに変わらない(ほとんど同じ もの )コンパイラですが、コンパイラ作成者は常に新しい翻訳とコードの改良または最適化(新しいものに対する操作)を追加しています。コンパイルと翻訳はより一般的には機能的言語のための「キラーアプリ」です。

1136
Norman Ramsey

必ずしも2つのパラダイムから選ぶ必要はありません。多くの機能概念を使ってOOアーキテクチャでソフトウェアを書くことができます。 FPとOOPは、事実上直交しています

例えばC#を取ります。あなたはそれがほとんどOOPであると言うことができますが、たくさんのFP概念と構成があります。 Linq を考えると、Linqが存在することを可能にする最も重要な構文は本質的に機能的です: ラムダ式

もう1つの例、F#あなたはそれがほとんどFPであると言うことができますが、利用可能なたくさんのOOPの概念と構造があります。クラス、抽象クラス、インタフェースを定義し、継承を扱うことができます。あなたのコードがより明確になるとき、あるいは劇的にパフォーマンスを向上させるとき、あなたは可変性さえ使うことができます。

現代の多くの言語はマルチパラダイムです。

おすすめの読み物

私は同じボートに乗っているので(OOPのバックグラウンド、FPの学習)、私はあなたが私が本当に感謝しているいくつかの読み物をお勧めします:

166
Bruno Reis

オブジェクト指向プログラミングは、以下を提供します。

  1. へのカプセル化
    • 内部状態のコントロール突然変異
    • 内部表現への結合を制限する
  2. サブタイピング、許可:
    • 互換性のある型の置換(多型)
    • クラス間で実装を共有するための粗雑な手段(実装継承)

関数型プログラミングは、Haskellで、あるいはScalaでさえ、型クラスのより一般的なメカニズムを通して代用を許可することができます。変更可能な内部状態は推奨されないか禁止されています。内部表現のカプセル化も達成できます。良い比較については Haskell vs OOP をご覧ください。

Normanの「機能プログラムに新しい種類のものを追加するには、新しいケースを追加するために多くの関数定義を編集する必要があるかもしれない」と主張しています。機能コードが型クラスをどの程度うまく採用しているかによって異なります。特定の抽象データ型でのパターンマッチングがコードベース全体に広がっている場合は、実際にこの問題に悩まされるでしょうが、おそらく最初から始めるのは悪い設計です。

_ modified _ 型クラスについて議論する際の暗黙の型変換への参照を削除しました。 Scalaでは、型クラスは変換ではなく暗黙のパラメータでエンコードされていますが、暗黙の変換は互換性のある型の代替を実現するためのもう1つの手段です。

31
retronym
  1. あなたがひどく並行した環境にいるなら、純粋な関数型プログラミングは便利です。可変状態の欠如は並行性をほとんど簡単にします。 Erlangを見てください。

  2. マルチパラダイム言語では、可変状態の存在が実装の詳細でなければならない場合、いくつかのものを機能的にモデル化することをお勧めします。したがって、FPは問題ドメインにとって良いモデルです。例えば、Pythonのリスト内包表記またはDプログラミング言語の std.range を参照してください。これらは関数型プログラミングに触発されています。

22
dsimcha