なぜ関数型プログラミングより命令型プログラミングが好ましいのですか?[閉まっている]


13

背景:私は、一般的なメンタルモデルが不可欠なプログラミングであるVB.NETショップで働く関数型プログラミングを提唱しています。システムの基盤はWinFormsであるため、命令型プログラミングから完全に逃れることはできないと理解できますが、そのメリットを信じているため、可能な限りFP(主にLinq経由)を使用しようとしています。

FPに対する議論と反論

  1. 流fluentなLinqは、このスタイルがシーケンスを別のシーケンスまで処理し、それを繰り返すという点で、命令型の対応するものよりも効率が低いことに気付くかもしれません。一般に、シーケンス上の繰り返しパスを避けるために最適化できる命令型アプローチよりも数パス多くかかります。このため、リードは、明らかに「効率が悪い」機能的アプローチを選択する理由を理解できませんでした。

    • 反論:CPUサイクルの観点からは効率が悪い場合がありますが、各行はシーケンスを通過するときに1つのことだけを行うため、人間が理解しやすく、追跡しやすいと感じました。私にとって、これは、自分のステーションの各人がやるべき仕事が1つしかない組立ラインがあるような気がします。効率の無視できるトレードオフは、懸念がきちんと分離されたコードによって補償されると感じています。
  2. 私の店で聞くFPに対する次の議論は、デバッグするのが難しいということです-それは本当です。Linqコードをステップオーバーするのは簡単ではありません。そして、すぐに見つけられない問題をよりよく追跡して分析するために、メソッドチェーンを解く必要がある場合があります。

    • _Counter-argument:ほとんどの場合、機能スタイルは読み方がより宣言的であり、エラーが機能チェーン内でスローされると、私は通常、問題をすぐに見つけることができるため、これには問題はありません。

私の質問

私は店で機能的なスタイルを宣伝しようとしてきましたが、私は前進しているとは感じません。私は両方のスタイルのプログラミングを行ってきましたが、最近Haskellに手を出したばかりです。長年の命令的な経験にもかかわらず、私はJavaScriptでFPを日常的に使用しているので、それは私に成長しました。命令型のスタイルにこだわった場合に行ったことと比較すると、コアの正当性のメモが鳴ります。私は脳を機能的思考、機能的構成に向けて再訓練しました。

私が理解できないのは、FPのメリットを他の人に納得させるのがどれほど難しいかです。

たとえば、私のショップの開発者はLinqを使用していますが、通常はドメインデータを処理するコンテキストで使用しています。私はより一般的な意味でそれを使用し、シーケンス/リストまたは永続的なデータ構造を扱うときはいつでもそれを好みます。チームメイトにLinqの使用を拡大するよう説得することができませんでした。

私が理解しようとしているのは、開発者がFPを好まない原因です。

FPの経験が豊富であるが、命令型を支持することに決めた人からの回答を期待したい。機能を使用するのではなく、命令にとどまるという決定を下した理由は何ですか?


命令型プログラミングと関数型プログラミングの違いを強調する追加の例を次に示します。

SelectedRowsLinqでグリッドのメソッドを次のように書きました。

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Return Me.ugrBase.Selected.Rows.
            OfType(Of Infragistics.Win.UltraWinGrid.UltraGridRow)().
            Select(Function(ugr) ugr.ListObject).
            OfType(Of DataRowView)().
            Select(Function(drv) drv.Row).
            ToArray
    End Get

ただし、このスタイルのコードは一部の開発者を不快にさせるため、当社のリードはそれをより馴染みのあるものに書き換えました。

Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
    Get
        Dim plstRows As New List(Of DataRow)
        For Each bugrLoop As Infragistics.Win.UltraWinGrid.UltraGridRow In Me.ugrBase.Selected.Rows
            If bugrLoop.ListObject IsNot Nothing Then
                plstRows.Add(CType(bugrLoop.ListObject, DataRowView).Row)
            End If
        Next
        Return plstRows.ToArray()
    End Get

私は関数型プログラミングが好きですが、コードをざっと見てみると、「命令型」(宣言型と呼んでいます)アプローチを好むでしょう。読みやすくなっています。これは私の経験であり、自分の環境の産物である可能性があります。とはいえ、簡単な5秒で準備手順と返品内容を確認できます。ループがあり、そのデータの調整がループ内で発生する可能性が高いことがわかります。関数定義を追跡する必要はありません。そこにあり、簡単です。しかし、FPはよりクリーンであり、学習曲線を超えると、おそらく同じくらい迅速にコーディングできます。
vol7ron

問題となるのは、特に多くの言語の「十分な」知識しか持たない人々と仕事をするときの学習曲線です。特定の言語に特化した場合、FPの方が優れた最初の試みになると確信しています。次に、非効率性(単体テストのパフォーマンス)があれば、実装でより明確にすることができます。
vol7ron

回答:


11

関数型プログラミングは、経験の浅いプログラマにとっては複雑すぎます。イラストの1つこの例で、4行のFPアナログと比較して、30-LOCの混乱が理解しやすく、わかりやすいと学生が宣言しました。

(これはFPの例の元のバージョンです。リンク内の回答は最近編集され、読みやすくなりました。)

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

関数型プログラミングでは、コーディングの方法とこのコードの実行方法について異なる考え方が必要です。これはめったに学生が大学で語られる方法ではなく、いったん悪い習慣をとると、それを変えることは困難です。

関数型プログラミングには、初心者には危険なように見える独自の機能もあります。遅延評価はその1つであり、遅延評価が優れた機能であり、迷惑ではない理由を理解するには、数か月かかる場合があります。

それが、非常に多くの初心者がHaskellのような言語ではなくPHPなどの言語でプログラミングを開始する理由でもあります。


8
私は、イントロコースにSchemeが使用されている大学で反対の経験をしました。学生がJavaまたはC#を習得しなければならなかったとき、Schemeの方が読みやすいと最も不満を感じていた
Daniel Gratzer

2
それは私のポイントを証明しています。何年も命令型プログラミングとOOPを学んだ学生は、それがより読みやすいと感じるでしょう。FPを使い始めた人は、命令型プログラミングと比較して、FPが読みやすいと感じるでしょう。FPパラダイムと非FPパラダイムを等しくよく知っている学生に何が起こるかを知ることは興味深いでしょう。
アルセニムルゼンコ

1
主な問題は、関数型言語が抽象化されていることです。評価されていないサンクを蓄積したためにメモリ不足になったとHaskellerが言った場合、間違いがあります。多くのアルゴリズムは、機能的なスタイルで記述されていると効率的ではありません。高速なクイックソート実装を実装することはできません。慣用的なHaskellで。すべてのインプレースアルゴリズムは、良好なパフォーマンスを得るためにIOアレイを実行することになります。関数型言語は言語純粋主義者向けであり、命令型言語は思考を時間内に完了させたい人向けです。
Kr0e

3
@ Kr0e:言語またはパラダイムに対する「抽象的すぎる」引数は、常に奇妙に見えます。すべての(またはほとんどの)言語に対して同じ引数が使用されました。うまくいけば、今日のほとんどのソフトウェアはアセンブラーで書かれていません。
Arseni Mourzenko

6
「関数型言語は言語純粋主義者向けであり、命令型言語は時間内に思考を終わらせたい人々向けです。」:私の経験によると、これは真実ではありません。関数型言語を使用すると、より迅速に処理を完了できます。命令型ははるかに冗長で宣言的ではないため、命令型言語を使用する必要がある場合は、物事を正しく理解する前に間違いなく反復が必要になります。
ジョルジオ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.