システムをモジュールに分解する際に使用される基準について という名前の古典的な記事があります。これは、初めて読んだばかりです。それは私には完全に理にかなっており、おそらくOOPが基にした記事の1つです。その結論:
これらの例を使用して、フローチャートに基づいてシステムをモジュールに分解することはほとんど常に正しくないことを実証しようとしました。 ...各モジュールは、そのような決定を他のモジュールから隠すように設計されています
私の無学で経験の浅い意見では、関数型プログラミングはこの記事とは正反対のアドバイスをしています。私の理解では、関数型プログラミングはデータフローを慣用的にしています。データは関数から関数に渡され、各関数はデータを密接に認識し、その過程で "changeing it" を行います。リッチヒッキーがデータの隠蔽が過大評価されているか、不必要であるかなどについて語ったリッチヒッキーの講演を見たことがあると思いますが、確かに思い出せません。
private
フィールドを持つことができます。 FPでは、これについての明確なアナロジーはありません。私はこれを見つけました ニール・フォードの話 それは非常に関連するスライドを持っています。ここにスクリーンショットを埋め込みます:
あなたが言及する記事は一般にモジュール性についてであり、それは構造化された機能的なオブジェクト指向プログラムにも等しく適用されます。私は以前、大きなOOP=男だった人からその記事を聞いたことがありますが、何かについてOOP特定ではなく、プログラミングに関する記事として読んでいます。関数型プログラミングに関する有名な記事 なぜ関数型プログラミングが重要か であり、結論の最初の文には「このホワイトペーパーでは、モジュール化がプログラミングの成功の鍵であると主張しました。」とあります。 (1)の答えは「いいえ」です。
適切に設計された関数は、必要以上にデータを想定していないため、「データを密接に認識する」という部分は間違っています。 (または、少なくともOOPの場合と同じくらい間違っています。高水準の抽象化で厳密にプログラムし、すべてのパラダイムですべての詳細を永久に無視することはできません。結局、プログラムの一部は実際にデータの具体的な詳細。)
データの非表示はOOP=特定の用語であり、記事で説明されている情報の非表示とは完全に同じではありません。記事での情報の非表示は、行うのが困難または困難であった設計上の決定に関するものです変更される可能性があります。データ形式に関するすべての設計決定が難しいまたは変更される可能性があるわけではありません。また、変更が難しいまたは変更される可能性があるすべての決定がデータ形式に関するものであるとは限りません。個人的には、OOプログラマーはすべてをオブジェクトにしたい場合がありますが、単純なデータ構造で十分な場合もあります。
編集:私は Rich Hickeyへのインタビュー から関連する引用を見つけました。
Fogus:その考えに従います—一部の人々は、Clojureがそのタイプのデータ非表示カプセル化に従事していないという事実に驚いています。データを非表示にすることをやめたのはなぜですか?
ヒッキー:Clojureはプログラミングを抽象化することを強く強調しています。ただし、ある時点で、誰かがデータにアクセスする必要があります。また、「プライベート」の概念がある場合は、対応する特権と信頼の概念が必要です。そして、それは全体のトンの複雑さと少しの価値を追加し、システムに剛性を作成し、そして多くの場合、物事を本来あるべきでない場所に住まわせます。これは、単純な情報がクラスに入れられるときに発生する他の損失に追加されます。データが不変である限り、誰かが変化する可能性のあるものに依存するようになる可能性があることを除いて、アクセスを提供することによってもたらされる可能性のある害はほとんどありません。ええ、そうですね、人々は実生活でそれを常に行っており、物事が変化するとき、彼らは適応します。そして、彼らが合理的であるならば、彼らは将来彼らが適応する必要があるかもしれない変化することができる何かに基づいて彼らが決定をするときを知っています。ですから、それはリスク管理の決定です。プログラマーは自由に作れるべきだと私は思います。抽象化するようにプログラミングしたいという欲求や、実装の詳細との結婚に警戒心がなければ、優れたプログラマーになることはできません。
...そしておそらくOOPが基にした記事の1つです。
実際にはそうではありませんでしたが、特に、当時彼が論文で説明した最初の基準を使用してシステムを分解するように訓練されていた実務家にとって、それは議論に追加されました。
まず、私の評価が正しいかどうかを知りたいです。 FPパラダイムとこの記事は哲学的に反対ですか?
さらに、私の目には、FPプログラムがどのように見えるかについての説明は、プロシージャや関数を使用する他のどのプログラムとも変わりません。
データは関数から関数に渡され、各関数はデータを密接に認識し、途中で「変更」します。
...exceptは「親密さ」の部分です。なぜなら、親密さを正確に回避するために、抽象データを操作する関数を使用できる(そしてそうすることが多い)からです。したがって、「親密さ」をある程度制御でき、非表示にしたいものにインターフェース(つまり、関数)を設定することで、好きなように調整できます。
したがって、関数型プログラミングを使用して情報を隠すというParnasの基準に従えず、KWICインデックスの実装になり、彼の2番目の実装と同様の先の尖った利点が得られない理由はわかりません。
彼らが同意すると仮定すると、私はデータ隠蔽のFP実装が何であるかを知りたいのです。これをOOPで見るのは明らかです。クラス外の誰もがアクセスできないプライベートフィールドを持つことができます。 FPでは、これについての明確なアナロジーはありません。
データに関する限り、FPを使用してデータの抽象化とデータ型の抽象化を作成できます。これらはいずれも、抽象化として機能を使用して、コンクリート構造とこれらのコンクリート構造の操作を隠します。
[〜#〜]編集[〜#〜]
FPのコンテキストで「データを非表示にする」ことはそれほど有用ではない(またはOOP風(?))とするアサーションの数が増加しています。 SICPのシンプルで明確な例:
システムが有理数を処理する必要があるとします。それらを表現する方法の1つとして、分子と分母の2つの整数のペアまたはリストを使用できます。したがって:
(define my-rat (cons 1 2)) ; here is my 1/2
データの抽象化を無視すると、おそらくcar
とcdr
を使用して分子と分母が得られます。
(... (car my-rat)) ; do something with the numerator
このアプローチに従って、有理数を操作するシステムのすべての部分は、有理数がcons
であることを認識します-それらは、有理数を作成し、リスト演算子を使用してそれらを抽出するcons
番号になります。
直面する可能性のある1つの問題は、有理数の形式を減らす必要がある場合です。システム全体で変更が必要になります。また、作成時に削減を決定した場合、合理的な用語の1つにアクセスするときに削減する方が後で、フルスケールの別の変更が得られることがわかります。
もう1つの問題は、仮説的に、それらの代替表現が優先され、cons
表現を放棄することにした場合(フルスケールの変更を再度)です。
これらの状況に対処するための正気な努力は、おそらく、インターフェースの背後にある有理数の表現を隠し始めます。最後に、次のような結果になる可能性があります。
(make-rat <n> <d>)
は、分子が整数<n>
であり、分母が整数<d>
である有理数を返します。
(numer <x>)
は、有理数<x>
の分子を返します。
(denom <x>)
は、有理数<x>
の分母を返します。
そして、システムはもはや合理的論理が何でできているのかを知ることはありません(そしてもはやそうすべきではありません)。これは、cons
、car
、cdr
が有理数に固有ではなく、make-rat
、numer
、denom
areであるためです。もちろん、これは簡単にFPシステムになる可能性があります。そのため、「データの非表示」(この場合、データの抽象化、または表現と具体的な構造をカプセル化する取り組み)は、 OO、関数型プログラミングなどのコンテキストに関係なく、広く使用および調査されている関連概念と手法。
そして要点は...彼らがしている「隠蔽の種類」またはカプセル化を区別しようとするかもしれないが(彼らが設計決定、またはデータ構造またはアルゴリズムを隠しているかどうか-手続き型抽象の場合)、 それらのすべては同じテーマを持っています:それらはパルナスが明示した1つ以上のポイントによって動機付けられます。あれは:
上記の例はSICPの本から取られたので、本のこの概念の完全な議論と提示のために、私はチェックすることを強くお勧めします 2章 。また、FPのコンテキストで抽象データ型を理解することをお勧めします。これにより、表に他の問題が生じます。
関数型プログラミングにはデータの非表示がないというあなたの考えは間違っています。データを非表示にする方法は異なります。関数型プログラミングでデータを非表示にする最も一般的な方法の1つは、関数を引数としてとる多態性関数を使用することです。たとえば、この関数
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
データの最も外側の構造(つまり、リスト)しか見ることができません。リストに含まれるデータについては何も見ることができず、渡された単一の関数を介してのみデータを操作できます。
引数として渡される関数は、リストに含まれるデータ型のパブリックメソッドに似ています。データを操作する方法は限られていますが、データ型の内部動作は公開されていません。
ここには少し矛盾があります。関数型プログラミングは関数に重点を置いており、多くの場合、プリミティブデータ型に直接作用する関数を備えていますが、オブジェクト指向プログラミングよりもmoreデータが非表示になる傾向があります。
どうですか?ニースについて考えてみてくださいOO基礎となるデータを非表示にするインターフェイス-おそらくコレクション(私はほぼどこにでもあるものを選択しようとしています)。コレクション内のオブジェクトの基礎となるタイプを知る必要がない場合や、コレクションが実装していることがわかっている限り(たとえば、IEnumerable)、コレクションを実装しているオブジェクトのタイプなので、データを非表示にできます。
関数型プログラミングでは、IEnumerableインターフェイスで効果的に機能するが、プリミティブデータ型(または任意のデータ型)で動作する関数を作成する場合があります。しかし、型がIEnumerableメソッドを実装しなかった場合はどうなりますか?ここに鍵があります「インターフェース」の必要な部分を形成する「メソッド」は常に、関数に渡されるパラメーターにすることができます。または、データと関数を組み合わせて、 OOのような方法。
どちらの方法でも、オブジェクト非表示よりもデータ非表示が少なくないことに注意してください。 anyタイプで機能する私の一般的な関数は、明らかにそのタイプのデータにアクセスしていません-これは、一般的な関数にパラメーターとして渡される関数内で発生しますが、一般的な関数は、これらの関数の内部を覗いて見ることはありませんデータ。
したがって、あなたのポイント1に関しては、FPであり、記事が実際に同意しないとは思いません。FPの特徴が隠れていないとは思わない確かに、FPで作成者が好んだ設計を実装することができます。
ポイント4(2と3は、ポイント1について私が言ったことを考えると、答える意味がありません)までは異なります。また、OO言語によっても異なります。多くのプライベートフィールドでは、言語によって強制されるのではなく、慣例によりプライベートです。
私はここで手足を三振して、FP OOでの方法とは異なり、この概念は関係がないと言います。
tl; dr;データを非表示にするポイントは、責任が本来あるべき場所に維持されるようにすることであり、知識のないデータを外部のアクターがいじくり回すことはありません。 FPでは、データは式によって生成されます。この方法では、ゲームのルールを完全に変更する合成可能な計算ほど変更可能なプロパティではないため、データをいじることはできません。
私のFPの経験では、確かに取るに足らないものですが、私はOOとの明確なコントラストをよく/一般的なデータモデリングを表すものに見出す傾向があります。
これとは対照的に、OOでは一般に、データを表すために物事をモデル化します。義務的な自動車の例:
[〜#〜] oo [〜#〜]
ここで注意する点は、OO形式で物事をモデル化しているときは、物事をデータとして表すことです。プロパティを持つオブジェクトがあり、それらのプロパティの多くは、より多くのプロパティを持つオブジェクトです。あなたはあちこちにいくつかのメソッドをそれらのオブジェクトにアタッチしていますが、それらが実際に行うことは通常、オブジェクトのプロパティをこのように揺らすことであり、これも非常にデータ中心のモデリングです。つまり、データをフォーカスと相互作用するようにモデル化しますデータのすべてのポイントを利用できるように構成して、消費者がデータをこのように変更できるようにします。
[〜#〜] fp [〜#〜]
OOとFPが常に私に影響を与えることの大きな違いは、データをモデル化する方法の上で述べたとおりです。OO =上記のように、データをデータとしてモデル化します。FPでは、データを計算、式、アルゴリズムとしてモデル化します。これは、事実ではなく、データのアクティビティをモデル化することについてです。基本的なデータについて考えてください。数学でのモデリングでは、OOとは対照的に、モデリングは表現する方法を考え出しています。これとは対照的に、データを生成できるアクティビティを取得する方程式を取得することです。あなたが持っているデータです。つまり、FPとOOの違いはmuchです。
非常に長い間、基本的なFP言語の1つであるLISPは、非常に少量のプリミティブデータ型で動作していました。これは、アプローチがの複雑な表現のモデリングに関するものではないため機能しますシステムの動作を生成および表現する計算と同じくらいにデータ。
FPでコードを書き始めるときは、何かを行うコードを書くことから始めます。OOでコードを書き始めるときのように、何かを記述するモデルを書くことから始めます。 FPは式であることで、物事の実行は非表示になり、OOはデータで記述されることで物事の実行は非表示になります。
手元の質問に戻ります。FPデータの非表示について何と言いますか、それを高く評価しますか、それとも反対しますか?
OOで重要ではないと私は言います。あなたのデータは、干渉されないように隠す必要があるプログラム内の重要な部分です。= In FPシステムの根性と知識は、システムを表現するアルゴリズムと計算にすべて隠されています。これらは、定義により、ほぼ不変です。計算式を変更する唯一の方法は、マクロのようなものですが、それでも突然変異の定義ですそれ以上は操作できない表現そのものです。
TL; DR:いいえ
いいえ、ありません。関数型プログラミングは宣言型です "コンピュータープログラムの構造と要素を構築するスタイルであり、制御フローを記述せずに計算のロジックを表現します。" フローチャートに従うことなどよりは重要ではありません。フローを独自に発生させるルールを作成します。
手続き型プログラミングは、関数型プログラミングよりもフローチャートのエンコーディングに非常に近いものです。したがって、発生する変換、およびそれらの変換を、フローチャートのフローとまったく同じように、順番に実行されるプロシージャにエンコードします。
まず、この素晴らしい記事へのリンクのおかげで、私はこれまでこれを知りませんでした、そしてそれは私がここ数年コミュニティーの他のソフトウェアデザイナーと話し合っているいくつかのことについていくつかの素晴らしいインプットを与えてくれました。これについての私の意見は次のとおりです。
まず、私の評価が正しいかどうかを知りたいです。 FPパラダイムとこの記事は哲学的に反対ですか?
FPの設計は、データフローに非常に重点を置いています(これは、記事が示唆するほど私見では悪くありません)。これが完全な「不一致」である場合は、議論の余地があります。
FP「データの非表示の欠如」をどのように「補正」するのでしょうか?データの非表示を犠牲にしますが、X、Y、Zを獲得します。Xの理由を知りたいのですが。 、Y、Zは、データを隠すよりも有益であると考えられています。
私見それは補償しません。下記参照。
あるいは、彼らが同意しないと仮定すると、おそらくFPはデータの非表示が悪いと感じています。そうであれば、データの非表示が悪いと思うのはなぜですか?
FPユーザーまたはデザイナーがこのように感じたり考えたりすることはほとんどないと思います。以下を参照してください。
彼らが同意すると仮定して、データ隠蔽のFP実装とは何かを知りたいのですが。これをOOPで見るのは明らかです。クラス外の誰もがアクセスできないプライベートフィールドを持つことができます。 FPでは、これについての明確なアナロジーはありません。
ここにポイントがあります-あなたはおそらくあなたが信じるほど多くのOOP非機能的な方法で実装されたシステムを見てきたOOPは非機能的です。そしてそれは誤解、IMHO OOPとFPは主に直交する概念であり、完全に機能的なOOシステムを構築できるため、 FPの古典的な「オブジェクト」実装は closures を使用して行われます。オブジェクトを機能システムで使用したい場合は、重要な点は、それらを不変に設計することです。
したがって、より大きなシステムを作成するために、IMHOはOOの概念を使用して、記事の「モジュール化2」で説明されている方法とまったく同じように、「FPパス」を離れずにモジュール、クラス、およびオブジェクトを作成できます。お気に入りのモジュールの概念を使用するFP言語、すべてのオブジェクトのみを不変にして、「両方の長所」を使用する。