関数型プログラミングのためのメンタルモデルまたは実世界の比phor


16

現実世界の何かを参照する機能プログラミングの優れたメンタルモデルやメタファーを持っている人はいますか?

オブジェクト指向プログラミングは直感的に理にかなっています。プロパティを持っているものがありますが、時にはプロパティを操作したり、プロパティ(メソッド)を計算したりすることもできます。(例:車、形、猫)。

私は関数型プログラミングに何の害もないし、2つの美徳についての議論には興味がありません。オブジェクト指向プログラミングと同じように、メタファーまたはメンタルモデルが必要です。

機能的パラダイムでプログラミングするための優れたメンタルモデルまたは現実世界のメタファーとは何ですか?機能を処理する機能で構成される機能については、立ち上がって発言するための確固たる場所がなくなります。


「関数型プログラミング」の具体的な意味は、「副作用なし/宣言的」または「ファーストクラスの関数/関数構成」ですか?または両方?
acelent 14年

興味深い質問。「関数型プログラミング」に関する私の現在の小さな知識とプログラミングの経験が少ないため、その質問に有意義に答えることはできません。推測を避けるために、両方を言うでしょう。
グイドアンセルミ14年

13
「実世界」モデルは、オブジェクト指向プログラミングの動機としてしばしば与えられます。OOPのオブジェクトは実際のオブジェクトに常に対応するとは限らず、たとえそうであっても対応が不完全なことが多いため、最終的には成長すべきアプローチだと思います。たとえば、「is-a」関係は常に同じではありません。一方、「現実の世界」の何かに基づいたプログラミング言語のモデルまたはメタファーが必要だと言ったら、この限られた形式のOOPに本質的に制限されていると思います。
デビッドK 14年

Unixのようなシステム(または最新のWindowsのpowershell)の使用経験がある場合、本当に優れたメンタルモデルはシェルワンライナーです。シェルパイプは機能的ではなく技術的にフローベースのプログラミングであるため、まったく同じではありませんが、プログラマーと同じ「感覚」を持っています。
スリーブマン14年

1
また、関数型言語では、関数型プログラミングでは、オブジェクト指向は、たとえば正規表現のようなツールとして扱われます。必要に応じて使用できますが、必要はありません。lispやtclなどの一部の言語では、オブジェクト指向は言語に組み込まれた機能ではなく、使用できるライブラリです(または、勇気があれば独自のオブジェクト指向を作成することもできます)。したがって、自然にオブジェクト指向ソリューションを持っている問題は、ほとんどの関数型言語でオブジェクト指向を使用して解決できます。人々はオブジェクト指向を宗教として扱わないだけです。
スリーブマン14年

回答:


32

関数型プログラミングとは、結果を達成するために小さな関数を結合することです。まともなメンタルモデル(少なくとも、私にとって)は組み立てラインです。構成される各関数は、アセンブリプロセスのもう1つのステップです。ここでこの機能を検討してください。

smallest  = head . sort

Haskellでは、この関数はリスト内の最小の要素を返します。アセンブリーラインは最初に入力を並べ替え、次に最初の要素を返します(並べ替えが最小から最大の場合)。最小の偶数値のみを取得する場合は、アセンブリーラインを次のように変更できます。

smallestEven = head . sort . filter even

コンベアベルト上のもう1つのステップです。

簡単に言えば、関数は生の入力(パーツ)を処理済みの商品(出力)に変換するために実行されるステップを記述するだけです。


2
グローバル変数を持たない純粋な関数型言語では、1つのアセンブリーラインが他のアセンブリーラインに影響を与えることはできません(理論的には、互いに依存しないアセンブリーラインは並列に実行できますが、私はそうではありませんコンパイラがこれを行うかどうかを確認してください。
bstamour

3
@GuidoAnselmiこれについて考える1つの方法は、関数型プログラミングのアセンブリラインは入力をそのままにして新しい出力を作成するのに対し、従来のOOPのアセンブリラインは入力を変換することです。
ドーバル14年

2
この比phorは、「副作用/宣言なし」ではなく、「関数プログラミング」の「ファーストクラスの関数/関数構成」の意味でのみ意味を持ちます。また、オブジェクト指向プログラミングには必ずしも副作用がないため、OOPまたはこのFPの意味を使用して、破壊的または建設的なアセンブリラインを実装できます。OOPは、副作用よりもカプセル化、メッセージパッシング、およびポリモーフィズムに関するものであり、物事のモデル化方法に依存します。たとえば、最初から最後まで参照IDが必要ですか?
acelent 14年

3
@bstamour:正確には、その(f . g) (x)手段f(g(x))またはf . g手段を記述する必要があります\x -> f (g (x))
ジョルジオ14年

3
@MarjanVenema物事はその一例では、左に流れるだけそれがどのようなので.定義されています。これはHaskellの一般的な仕組みはありません。|>HaskellでF#のフォワードパイプ演算子()を定義して書き込むsmallest x = (sort x) |> headと、データが正しく流れるようになります。私はそれを指摘すると思いました。
ドーバル14年

18

誰もが関数型プログラミングの優れたメンタルモデルを持っていますか?

数学。関数型プログラミングは数学にヒントを得てモデル化されています。数学関数には状態がなく、副作用などもありません。したがって、FPにもあります。OOスタイルの「これをどうやってやるのか」というアプローチを使用するのではなく、数学関数の観点からFPについて考える場合、良い形になります。ただし、オブジェクト指向の感度をFPに持ち込もうとすると、流れに逆らって泳ぎます。


1
ありがとう。ただし、現実世界からの比phorが必要です(たとえば、コンピューターや数学からではありません)。
グイドアンセルミ14年

3
@GuidoAnselmi:関数はブラックボックスです。何かを片側に入れると、新しいものが反対側から出てきます。同じものを入れると、常に同じものが出てきます。これらの小さな箱をたくさん取り、それらをさまざまな順序で組み合わせて、原金属を取り込んで車を生産する工場を建てることができます。プロセスの内部は多くの部分に分割されていますが、外部からは単なる別の機能です。
デニーズ14年

16

どの程度パラパラマンガ

フリップブックでは、各ページは、ある瞬間に存在する世界を表します。私たちのプログラムでは、世界はいくつかの複合データ構造として表されています(たとえば、ジャングルにいる木にいるゴリラの手にバナナがある)。後続の各ページは、前の表現をわずかに変更することでストーリーを進めます。FPでは、永続的なデータ構造は、以前の構造を効率的に再利用するように設計されていたため、変更は完全に新しいレンディションではなくデルタのみを提供します。

明らかではないかもしれないのは、フリップブックのページも無形のものを表しているということです。たとえば、ゴリラがバナナを落とすと、ジャングルの床に向かって重力と重力の効果を適用し始めます。これに対応するために、速度や軌跡などの属性をバナナに添付します。

私たちのプログラムには、フリップブックページ(別名、世界の状態)を引数として受け入れ、新しいページ生成する関数があります。このようにして、既存のオブジェクトの状態を実際に変更することなく、ストーリーが語られます。効果的に計算されるものを使用して、各ページを新しいページに置き換えるだけです。


3

関係。

友人:2人の場合、友人関係はこれらの一般法則に従います

  1. お互いに対して善意を持つ
  2. お互いを友だちだと思う
  3. お互いの時間を楽しんでいます

モノイド:複数のアイテムと、2つのアイテムを取り、1を返す関数を指定すると、モノイドの関係はこれらの一般的な法則に従います。

  1. 他のアイテムとともに関数に渡されるアイテムの1つ(アイデンティティと呼ばれる1つのみ)があり、関数が常に他のアイテムを返すようにします(0 + 1 = 1、したがって、アイテムが数字であり、機能は追加です)
  2. この関数は、セット内にないアイテムに対して操作したり、返したりすることはできません。
  3. この関数は連想的であり、アイテムとは多少独立した方法で使用できます。つまり、a *(b * c)=(a * b)* cは、aにb * cまたはcの結果を乗算できることを意味します。 a * bの結果によって、結果は最初に行ったものと同じになります。

関数型プログラミングは一般化に関するものであり、友人は非常に一般的な関係であり、多くのシナリオで見ることができますが、さまざまな形式では一般的に上記の法則に従います。

物事間の関係を支配する法則を認識し、そのタイプの関係を持つ物事のあらゆる形式で機能する一般的な実装を作成できます。関数型プログラミングでは、物事間の関係を特定して、それらを一般的に分類および処理できるようにします。

現実世界からの比metaが必要ですか?物事がどのように関連しているかを見て、一般的な法律を特定しようとします(法律以外のものが異なる場合がある複数のシナリオに適用可能)。店員と店の買い物客の間には関係があり、いくつかの一般的な法律があり、POSシステムの方法でその一般的な関係の人々の目標を促進するためにソフトウェアが開発されました。同様に、物事がどのように関係するかを規定するこれらの一般的な法則を見始めたら、関係のインスタンスの特定の詳細ではなく、ソフトウェアを書く際にそれらの関係の法則に依存し始めることができます。


2

すべてが値であり、関数を値に適用して(関数である可能性があります)、新しい値を生成します(できれば副作用は発生しません)。


ありがとう。残念ながら、それは説明よりもメンタルモデルやメタファーのように聞こえます。(コンピューターからではなく)現実世界からのメタファーが必要です。
グイドアンセルミ14年

1
以下のようカレブが指摘する、機能的なプログラミングモデルの数学ではなく、現実の世界。数学のレンズを通して現実の世界をモデル化できますが、FPは永続的なアイデンティティと可変状態を持つものの概念を排除するので、満足できるメタファーは見つかりません。必要に応じて、OOPがどのようにFPにマップするかを指摘することもできますが、それでもなお望みの答えにはなりません。
ドーバル14年

しかし、数学は実世界に基づいています。1太陽、9惑星。2個のリンゴと2個のリンゴは4個のリンゴになります。
グイドアンセルミ14年

また、関数型プログラミングでは、太陽、惑星、リンゴの型を設定し、太陽型の値を1つ、惑星型の値を9つ作成し、リンゴ型の追加を定義することもできます。
ドーバル14年

3
@GuidoAnselmiあなたはそれを完全に後方に持っています、人々は数学で現実世界を分析します、それは現実世界に基づいていません。数学は、実在するものでもそうでないものでも、あらゆる種類のものの間の関係を分析および定義するために使用されます。9惑星とは、数学的分析関数(カウント)を使用して、数学的構造(自然数のセット)を実世界の構造(惑星)に適用することです。現実の世界には9つの惑星はありませんが、それが持っているものがあります。数学は、シンボルが互いに関係を持っているもののシンボル表現について話しているだけです。
ジミーホファ14年

1

関数型プログラミングについて理解するための重要なことは、すべてが値であるということです。コード自体も「値」です。

シンプルで機能的なプログラミング環境の最良の例は、みんなのお気に入りのビジネスツールであるスプレッドシートです。スプレッドシートのすべてのセルは、データ、または関数の結果です。さらに、この関数は別のセルを変更することはできません。

およびのデカルトグリッドではなく、関数型言語に移行するA1B42、関数には名前が付けられます。それだけです。

これを超えて追加できる他の側面もありますが、それはその中心で機能的なプログラミングです。リストの構造や物事のグループ化について心配する必要はありません。関数型プログラミングとは、値を関数に渡し、メモリの他の場所をいじることなく値を取得することです。

それでおしまい。関数型プログラミングは、グリッドではなく名前の付いたスプレッドシートです。


0

関数型プログラミングは、動作に関するものと考えることができます。プログラムとは、コンピューターに実行させる動作の説明です。関数は振る舞いの基本単位であり、関数合成は小さな振る舞いから大きな振る舞いを構築する1つの方法です。

OOPでは、コードオブジェクトをすることを意図していることが問題領域内のオブジェクトの状態。そのドメインオブジェクトの変更を反映するために時間とともに変化します。FPでは、値はドメインオブジェクトの状態を表します。変更されることはなく、異なる状態を表すために異なる値を作成するだけです。

機能モデルは、コンピューターが実際に行っていること、つまり表していることについて、もう少し正直だと思います。結局のところ、私はただnew Tesla()薄い空気の外を想起させることはできません。:)


-5

次のように多かれ少なかれそれらを分解すると仮定すると、文はオブジェクト指向よりも機能的です...

The brown cow is in the meadow across the deep river.

したがって、先頭のフレーズを見つけてから、残りを見つける必要があります。

The cow (brown)
the meadow (across)
the river (deep)

一度に:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

解析ツリー:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Par約は機能的思考に感染します。

ゴットリーブフレーゲ1890年代、アランチューリング(entchiedungsprobleme)1930年代、ノアムチョムスキー(1960年代)への帽子。


4
これは紛らわしい説明であり、私はFPに精通しています。
デニーズ14年

意味を理解せずにLispの形を模倣するように見える
Izkata
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.