web-dev-qa-db-ja.com

関数型プログラミングよりも命令型プログラミングが好まれるのはなぜですか?

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

FPに対する引数と反対引数

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

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

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

私の質問

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

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

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

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

FPの経験は豊富だが、命令型スタイルを優先して決定した人からの回答を希望します。関数型を使用する代わりに命令型のままでいることを決定したきっかけは何ですか?


これは、命令型プログラミングと関数型プログラミングの違いを強調する追加の例です。

LinqでグリッドのSelectedRowsメソッドを次のように記述しました。

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
13
Mario T. Lanza

関数型プログラミングは、経験の浅いプログラマにとって複雑すぎます。図の1つは これ です。ここでは、4行に比べて30-LOCの混乱は理解しやすく、直観的であると学生が宣言しましたFP analog.

(これは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つであり、遅延評価が優れた機能であり、煩わしさではない理由を理解し始めるまでに数か月かかる場合があります。

だからこそ、多くの初心者がPHPなどの言語でプログラミングを開始し、Haskellのような言語ではありません。

11