75

FP と OO が直交しているという考えを理解し、検証しようとしています。

まず、2 つの概念が直交するとはどういう意味ですか?

FP は可能な限り不変性と純粋性を奨励しますが、OO は状態と突然変異のために構築されているように見えます – 命令型プログラミングのわずかに組織化されたバージョンですか? オブジェクトが不変である可能性があることは理解していますが、オブジェクト指向は状態/変化を暗示しているようです。

それらは正反対のようです。それはそれらの直交性にどのように影響しますか?

Scala のような言語では、OO と FP の両方を簡単に実行できますが、これは 2 つのメソッドの直交性に影響しますか?

4

10 に答える 10

72

直交性とは、2 つのものが無関係であることを意味します。それは垂直を意味する数学に由来します。一般的な使用法では、2 つの決定が無関係であること、または別の主題を検討するときに 1 つの主題が無関係であることを意味する場合があります。ここで使用されているように、直交とは、1 つの概念が他の概念を暗示したり除外したりしないことを意味します。

オブジェクト指向プログラミング関数型プログラミングの 2 つの概念は、互いに互換性がありません。オブジェクト指向性は、可変性を意味するものではありません。従来の方法でオブジェクト指向プログラムを紹介された多くの人々は、C++、Java、C#、または可変性が一般的で奨励されている同様の言語を最初に使用することがよくあります (標準ライブラリは、人々が使用するさまざまな可変クラスを提供します)。したがって、多くの人がオブジェクト指向プログラミングを命令型プログラミングや可変性と関連付けていることは理解できます。

ただし、オブジェクト指向プログラミングは次のようなトピックをカバーしています。

  • カプセル化
  • ポリモーフィズム
  • 抽象化

これはいずれも可変性を意味するものではなく、関数型プログラミングを排除するものでもありません。そうです、それらは異なる概念であるという点で直交しています。それらは反対ではありません。どちらか一方、または両方を使用できます (またはどちらも使用できません)。Scala や F# などの言語は、両方のパラダイムを 1 つの言語に結合しようとします。

Scala は、オブジェクト指向プログラミングと関数型プログラミングの機能を統合するために設計されたマルチパラダイム プログラミング言語です。

ソース

F# は、単純なコードを記述して複雑な問題を解決するのに役立つ、.NET 用の簡潔で表現力豊かで効率的な関数型オブジェクト指向言語です。

ソース

于 2010-10-16T16:07:37.487 に答える
15

まず、2つの概念が直交しているとはどういう意味ですか?

これは、2つの概念に対照的なアイデアがないか、互いに互換性がないことを意味します。

FPは、可能な限り不変性と純度を促進します。そしてOOは、状態と突然変異のために構築されたもののように見えます(命令型プログラミングのわずかに組織化されたバージョン?)。そして、私はオブジェクトが不変である可能性があることを認識しています。しかし、OOは私にとって状態/変化を暗示しているようです。

彼らは反対のようです。それは彼らの直交性にどのように影響しますか?

Scalaのような言語を使用すると、OOとFPの両方を簡単に実行できますが、これは2つの方法の直交性に影響しますか?

OOは、カプセル化、オブジェクト構成、データの抽象化、サブタイピングによるポリモーフィズム、および必要に応じて制御されたミューテーションに関するものです(OOでも不変性が推奨されます)。FPは、関数の合成、制御の抽象化、および制約付きポリモーフィズム(別名パラメトリックポリモーフィズム)に関するものです。したがって、2つのアイデアは矛盾していません。それらは両方とも、1つの言語で確実に持つことができるさまざまな種類の力と抽象化メカニズムを提供します。実際、これはScalaが構築された論文です!

GoogleでのScalaExperimentの講演で、Martin Oderskyは、2つの概念(OOとFP)が互いに直交していると信じていることと、Scalaが2つのパラダイムをエレガントかつシームレスに統合してScalaコミュニティで一般に知られている新しいパラダイムにする方法を非常によく説明しています。オブジェクト機能パラダイム。あなたのために話を見る必要があります。:-)


オブジェクト関数型言語の他の例:OCamlF#Nemerle

于 2010-10-16T16:30:29.263 に答える
12

まず、2 つの概念が直交するとはどういう意味ですか?

お互いに影響を与えないということです。つまり、関数型言語はオブジェクト指向でもあるため、機能が低下するわけではありません。

それらは正反対のようです。それはそれらの直交性にどのように影響しますか?

それらが反対である場合 (つまり、純粋に関数型の言語がオブジェクト指向になる可能性はありません)、定義上、それらは直交していません。しかし、私はこれが事実であるとは信じていません。

オブジェクト指向は、状態と突然変異のために構築されたもののように見えます (命令型プログラミングのわずかに組織化されたバージョン?)。そして、オブジェクトは不変である可能性があることを認識しています。しかし、オブジェクト指向は状態/変化を暗示しているようです。

これはほとんどの主流の OO 言語に当てはまりますが、OO 言語がミュータブルな状態を持つ必要がある理由はありません。

言語にオブジェクト、メソッド、仮想継承、アドホック ポリモーフィズムがある場合、それはオブジェクト指向言語です (変更可能な状態があるかどうかに関係なく)。

于 2010-10-16T16:09:52.520 に答える
7

2 つの概念が直交するということは、それらが任意の特定の表現において任意の程度まで独立して実現できることを意味します。たとえば、音楽を例にとると、曲のハーモニーとリズミカルを分類できます。「ハーモニック」と「リズミカル」という 2 つの概念は、ハーモニックとリズミカルな曲、不調和とリズミックな曲があるという意味で直交していますが、ハーモニーと不整脈の曲だけでなく、不調和でリズミカルな曲もあります。

元の質問に適用すると、これは、Haskell などの純粋に関数型の非オブジェクト指向プログラミング言語、Eiffel などの純粋にオブジェクト指向の「非関数型」言語だけでなく、C などのどちらでもない言語や、どちらも Scala などです。

簡単に言えば、Scala がオブジェクト指向であることは、データを操作するメソッドでデータをカプセル化するデータ構造 (「クラス」と「特性」) を定義できることを意味し、これらの構造 (「オブジェクト」) のインスタンスが常に定義された状態 (そのクラスに配置されたオブジェクトのコントラクト)。

一方、Scala が関数型言語であるということは、変更可能な状態よりも不変の状態を優先し、関数はファースト クラス オブジェクトであり、他のオブジェクトと同様にローカル変数、フィールド、または他の関数へのパラメーターとして使用できることを意味します。これに加えて、Scala のほぼすべてのステートメントには値があり、関数型プログラミング スタイルを使用することをお勧めします。

さらに、オブジェクト指向プログラミングと Scala の関数型プログラミングの直交性は、プログラマーとして、目的に合うと思われるこれら 2 つの概念の組み合わせを自由に選択できることを意味します。変更可能なオブジェクトのみを使用し、関数をオブジェクトとしてまったく使用せずに、純粋に命令型のスタイルでプログラムを作成できます。一方、オブジェクト指向の機能を使用せずに、Scala で純粋に関数型のプログラムを作成することもできます。

Scala では、どちらか一方のスタイルを使用する必要はありません。問題を解決するために、両方の長所を選択できます。

于 2010-10-16T17:17:48.233 に答える
7

すべての分類と同様に、プログラミング言語を関数型、オブジェクト指向、手続き型などに分割することは架空のものです。しかし、分類は必要です。プログラミング言語では、一連の言語機能とその言語を使用する人々の哲学的アプローチによって分類します (後者は前者の影響を受けます)。

そのため、「オブジェクト指向」言語が「関数型」プログラミング言語の機能と哲学を採用することで成功する場合もあれば、その逆の場合もあります。しかし、すべてのプログラミング言語の機能と哲学に互換性があるわけではありません。

たとえば、OCaml のような関数型言語は、レキシカル スコープとクロージャによってカプセル化を実現しますが、オブジェクト指向言語は public/private アクセス修飾子を使用します。これらは本質的に互換性のないメカニズムではありませんが、冗長であり、F# のような言語 (明らかにオブジェクト指向の .NET ライブラリおよび言語スタックとの調和を目指したほとんど関数型の言語) は、橋渡しをするために長い道のりを歩まなければなりません。ギャップ。

別の例として、OCaml はオブジェクト指向に構造型システムを使用しますが、ほとんどのオブジェクト指向言語は名義型システムを使用します。これらはほとんど互換性がなく、興味深いことに、オブジェクト指向言語の領域内での非互換性を表しています。

于 2010-10-16T17:28:05.357 に答える
6

オブジェクトのアイデアは、不変の方法で実装できます。例として、Abadi と Cardelli による本 " A Theory of Objects " があります。この本は、これらのアイデアを形式化することを目的としており、オブジェクト指向プログラムについての推論がより単純になるため、オブジェクトには最初に不変のセマンティクスが与えられます。

この場合、従来はオブジェクトをインプレースで変更していたメソッドは、代わりに新しいオブジェクトを返しますが、以前のオブジェクトは保持されます。

于 2010-10-16T16:09:07.700 に答える
5

関数をオブジェクトとして実装したり、オブジェクトを関数のコレクションとして実装したりできるため、2 つの概念の間には明らかに何らかの関係があります。

FP は可能な限り不変性と純粋性を奨励します

あなたは純粋に関数型プログラミングについて話している。

オブジェクト指向は状態と突然変異のために構築されているようです

オブジェクトが変更可能である必要はありません。オブジェクトと突然変異は直交概念であると言えます。たとえば、OCaml プログラミング言語は、純粋に機能的なオブジェクトの更新のための構文を提供します。

Scala のような言語を使用すると、OO と FP の両方を簡単に実行できます

あまり。テール コールの最適化の欠如は、慣用的な純粋関数型コードの大部分がスタック フレームをリークするため、Scala でスタック オーバーフローを起こすことを意味します。たとえば、継続渡しスタイル(CPS) と、論文で説明されているすべての手法については、Bruce McAdamがまとめています。JVM 自体は末尾呼び出しの最適化ができないため、これを簡単に修正する方法はありません。

純粋関数型プログラミングとオブジェクト指向プログラミングの直交性に関しては、単純に純粋関数型プログラミングが小規模なプログラム (高階関数など) のみを扱うのに対し、オブジェクト指向プログラミングは大規模なプログラムを扱うため、少なくとも直交に近いと言えます。 -プログラムのスケール構造。これが、関数型プログラミング言語が通常、大規模な構造化のための他のメカニズムを提供する理由です。たとえば、Standard ML と OCaml の高階モジュール システム、Common Lisp の CLOS、Haskell の型クラスなどです。

于 2010-10-17T17:22:17.083 に答える
3

FP と OO の関係を理解するのに役立ったのは、SICP の本、特に「関数型プログラムのモジュール性とオブジェクトのモジュール性」のセクションでした。これらの問題について考えていて、週末に空きがある場合は、一読する価値があるかもしれません。最初の 3 つのチャプター、かなり目を見張るものがあります。

于 2010-10-18T19:39:43.723 に答える
2

OOP と FP の直交性に関する素晴らしい説明を見つけました。

基本的な考え方は次のとおりです。数式の AST を扱っていると想像してください。したがって、さまざまな種類の名詞 (定数、加算、乗算) とさまざまな動詞 (eval、toString) があります。

としましょう、式は(1 + 2) * 3です。その場合、AST は次のようになります。

       乗算
         / \
     追加3
      / \
     1 2

動詞を実装するには、すべてのタイプの名詞に対してその実装を提供する必要があります。それを表として表すことができます:

                +---------------------+-------------------------------------+
                | eval                | toString                            |
+---------------+---------------------+-------------------------------------+
| constant      | value               | value.toString                      |
+---------------+---------------------+-------------------------------------+
| addition      | lhs.eval + rhs.eval | lhs.toString + " + " + rhs.toString |
+---------------+---------------------+-------------------------------------+
| mutiplication | lhs.eval * rhs.eval | lhs.toString + " * " + rhs.toString |
+---------------+---------------------+-------------------------------------+

「直交性」は、OOPではこのテーブルを行で実装するという事実から来ています。すべての名詞をクラスとして表し、すべてのメソッドを実装する必要があります。

一方、 FPでは、このテーブルを列ごとに実装します— すべての動詞に対して関数を記述し、この関数は異なる型の引数に対して異なる反応を示します (おそらくパターン マッチングを使用します)。

于 2017-08-20T20:57:49.400 に答える
-1

直交。いいですね。あなたが教育を受けたなら、あなたはそれを少しバンドしてふりをすることができます。そのパラダイムに少し似ています。

それはすべて、あなたがどのサークルを旅するか、そして各タイプのプログラミング技術があなたに何を与えるかによって異なります。私はSSに関するいくつかの投稿を読みましたが、関数型プログラミング言語から来たほとんどの人は、関数型にしか行けず、他のことは思考や考え方に反するという事実に固執しています。

オブジェクト指向プログラミングは、主に状態をキャプチャし、状態を管理するオブジェクトの一部ではないものの影響を受けないように、この状態を可能な限りローカライズされた状態に保つことを目的としています。一方、関数型プログラミングは、状態の問題を別の観点から見て、状態をシステムから分離し、それを関数に還元しようとします。はい、コードで両方の手法を使用できますが、どちらもソフトウェアの設計をさまざまな角度から見ています。

関数型プログラミングの手法には大きな関心が寄せられています。これは主に、マルチコアチップや並列プログラミングを扱うときに状態に必要な管理のためです。現時点では、関数型プログラミングがこれに対処する上で優位に立っているようですが、オブジェクトを使用して同じ効果を達成することができます。問題の考え方が違うだけです。頭を悩ませる代わりに、可能な限り状態を取り除こうとするのではなく、デザイン内のオブジェクトを見て、デザインパターン、CRC、およびオブジェクト分析。しかし、オブジェクトがそこに登場する場所、および関数型プログラミングがはるかに難しい場所は、現実の世界を分析し、それを理解可能なコンピューター化されたシステムにマッピングすることです。たとえばOOでは、人物オブジェクトは、人物の状態に作用するメソッドを使用した状態のカプセル化です。関数型プログラミングでは、人は人のデータに作用するデータ部分と機能に分解されますが、データは1回だけ作成され、不変であるという条件が追加されます。

私はオブジェクト指向のバックグラウンドから来ていますが、マルチコアチップを扱うほとんどのオブジェクト指向言語では、主にコアプログラミング設計構造(スレッドやデリゲートなど)によって機能的なルートをたどり、疑似データオブジェクトを渡していることを認めなければなりません。これは、このスレッド化された設計にうまくマッピングされていないように見えるため、オブジェクト指向プログラミングの手法に疑問を投げかけました。

于 2010-10-19T00:54:06.377 に答える