Warum ist die Imperative Programmierung der Funktionalen vorzuziehen? [geschlossen]

13

Hintergrund: Ich bin Befürworter der funktionalen Programmierung und arbeite in einem VB.NET-Shop, in dem das vorherrschende mentale Modell die zwingende Programmierung ist. Die Grundlage unseres Systems ist WinForms. Ich kann verstehen, dass wir nicht ganz von der imperativen Programmierung loskommen, aber ich versuche trotzdem, FP (hauptsächlich über Linq) zu verwenden, wo immer es möglich ist, weil ich an seine Vorzüge glaube.

Argumente & Gegenargumente gegen FP

  1. Man könnte bemerken, dass fließendes Linq weniger effizient ist als sein zwingendes Gegenstück, da dieser Stil eine Sequenz bis zu einer anderen Sequenz verarbeitet und diese wiederholt. Im Allgemeinen dauert es ein paar Mal länger als der imperative Ansatz, der besser optimiert werden kann, um wiederholte Übergänge über eine Sequenz zu vermeiden. Aus diesem Grund konnte der Lead nicht verstehen, warum ich einen funktionalen Ansatz wählen würde, der eindeutig "weniger effizient" ist.

    • Gegenargument : Ich argumentierte, dass es, obwohl es in Bezug auf die CPU-Zyklen manchmal weniger effizient ist, meiner Meinung nach verständlicher und leichter zu befolgen ist, da jede Zeile beim Durchlaufen der Sequenz nur eines tut. Für mich fühlt es sich so an, als hätte man ein Fließband, an dem jeder an seiner Station nur eine Aufgabe hat. Ich bin der Meinung, dass der vernachlässigbare Nachteil der Effizienz durch Code kompensiert wird, dessen Anliegen sauber voneinander getrennt sind.
  2. Das nächste Argument gegen FP, das ich in meinem Shop höre, ist, dass es schwerer zu debuggen ist - was wahr ist. Es ist nicht einfach, über Linq-Code zu springen. Und manchmal muss ich eine Methodenkette auflösen, um Probleme, die ich nicht sofort erkennen kann, besser verfolgen und analysieren zu können.

    • _Gegenargument: Meistens habe ich kein Problem damit, da ich denke, dass der Funktionsstil aussagekräftiger ist, wenn ein Fehler in einer Funktionskette auftritt, kann ich das Problem normalerweise sofort erkennen.

Meine Frage

Ich habe versucht, den funktionalen Stil in unserem Geschäft zu fördern, und ich habe nicht das Gefühl, dass ich Fortschritte mache. Ich habe beide Arten der Programmierung gemacht und mich erst kürzlich in Haskell versucht. Trotz jahrelanger unerlässlicher Erfahrung, seitdem ich FP in JavaScript routinemäßig verwende, ist es auf mich angewachsen. In meinem Kern klingt es richtig, wenn ich es mit dem vergleiche, was ich getan hätte, wenn ich mich an einen imperativen Stil gehalten hätte. Ich habe mein Gehirn auf funktionales Denken, auf funktionale Komposition umgeschult.

Was ich nicht verstehen kann, ist, wie schwer es war, andere von den Verdiensten von FP zu überzeugen.

Zum Beispiel verwenden die Entwickler in meinem Shop Linq, aber ich denke, sie verwenden es im Allgemeinen im Kontext des Umgangs mit Domänendaten. Ich benutze es allgemeiner und bevorzuge es, wenn ich mit Sequenzen / Listen oder persistenten Datenstrukturen zu tun habe. Ich war nicht in der Lage, meine Teamkollegen davon zu überzeugen, den Einsatz von Linq zu erweitern.

Ich versuche zu verstehen, warum ein Entwickler FP nicht mag.

Ich würde gerne eine Antwort von jemandem sehen, der viel Erfahrung mit FP hat, sich aber für den imperativen Stil entschieden hat. Was war der Grund für die Entscheidung, bei Imperativ zu bleiben, anstatt Funktional zu verwenden?


Hier ist ein zusätzliches Beispiel, das die Unterschiede zwischen imperativer und funktionaler Programmierung hervorhebt.

Ich habe die SelectedRowsMethode unseres Rasters in Linq so geschrieben:

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

Diese Art von Code macht es einigen Entwicklern jedoch unangenehm, und so hat unser Lead ihn an die Vertrauten weitergegeben:

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
Mario T. Lanza
quelle
Ich mag funktionale Programmierung, aber bei einem kurzen Blick auf den Code würde ich den „imperativen“ Ansatz (ich nenne ihn deklarativ ) vorziehen . Es ist viel einfacher für mich zu lesen - vorausgesetzt, dies könnte meine Erfahrung sein und ein Produkt meiner Umgebung sein. Davon abgesehen kann ich nach nur 5 Sekunden die Vorbereitungsschritte und die Rückgaben sehen. Ich kann sehen, dass es eine Schleife gibt und weiß, dass Anpassungen an diesen Daten höchstwahrscheinlich darin stattfinden würden. Ich muss keine Funktionsdefinitionen finden. es ist da, es ist einfach. Aber FP ist sauberer und wenn die Lernkurve einmal überschritten ist, wäre es wahrscheinlich genauso schnell zu programmieren.
vol7ron
Es ist die Lernkurve, auf die es ankommt, besonders wenn man mit Leuten zusammenarbeitet, die nur "gerade genug" von vielen Sprachen beherrschen. Wenn Sie sich auf eine bestimmte Sprache spezialisieren, ist FP sicher der beste erste Versuch. Wenn es dann Ineffizienzen (Unit-Test-Performance) gäbe, könnte man bei ihren Implementierungen expliziter sein.
vol7ron

Antworten:

11

Funktionale Programmierung ist für unerfahrene Programmierer einfach zu kompliziert . Eine der Abbildungen ist dies ein , wo die Schüler , dass 30-LOC Chaos erklärt war einfacher und intuitiver im Vergleich zu den vier Linien FP analog zu verstehen.

(Dies ist die Originalversion des FP-Beispiels, da die Antwort im Link kürzlich bearbeitet wurde, um die Lesbarkeit zu verbessern.)

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)));

Die funktionale Programmierung erfordert eine andere Denkweise in Bezug auf die Art und Weise, wie wir Code erstellen und wie dieser Code ausgeführt wird. Dies ist selten die Art und Weise, wie den Schülern am College gesagt wird, und wenn sie schlechte Angewohnheiten haben, ist es schwierig, sie zu ändern.

Die funktionale Programmierung hat auch ihre eigenen Besonderheiten, die in Anfängerhänden als riskant erscheinen können . Lazy Evaluation ist eine davon, und es kann Monate dauern, bis man begreift, warum Lazy Evaluation ein hervorragendes Merkmal und kein Ärger ist.

Das ist auch der Grund, warum so viele Anfänger anfangen, mit Sprachen wie PHP und nicht mit Sprachen wie Haskell zu programmieren.

Arseni Mourzenko
quelle
8
Ich habe die gegenteilige Erfahrung an einer Universität gemacht, an der das Schema für den Einführungskurs verwendet wird. Als die Schüler Java oder C # lernen mussten, beklagten sich die meisten, dass das Schema besser lesbar sei
Daniel Gratzer,
2
Das beweist meinen Standpunkt. Schüler, die jahrelang Imperative Programmierung und OOP gelernt haben, würden es besser lesen. Leute, die mit FP angefangen haben, werden es besser lesbar finden als imperative Programmierung. Es wäre interessant zu wissen, was mit Studenten passiert, die FP- und Nicht-FP-Paradigmen gleichermaßen gut kennen.
Arseni Mourzenko
1
Das Hauptproblem ist, dass funktionale Sprachen zu viel abstrahieren. Wenn ein Haskeller Ihnen mitteilt, dass Ihnen der Speicher ausgeht, weil Sie unbewertete Thunks angesammelt haben, stimmt definitiv etwas nicht. Viele Algorithmen sind nicht effizient, wenn sie in einem funktionalen Stil geschrieben sind. Sie können kein schnelles Quicksort-Werkzeug implementieren. im idiomatischen Haskell. Jeder In-Place-Algorithmus führt IO-Arrays aus, um eine gute Leistung zu erzielen. Funktionale Sprachen sind für Sprachpuristen, imperative Sprachen sind für Menschen, die rechtzeitig überlegen wollen.
Kr0e
3
@ Kr0e: das argument "abstracts too much" gegen eine sprache oder ein paradigma kommt mir immer komisch vor. Das gleiche Argument wurde gegen alle (oder die meisten) Sprachen verwendet; hoffentlich ist die meiste Software heute nicht in Assembler geschrieben.
Arseni Mourzenko
6
"Funktionale Sprachen sind für Sprachpuristen, imperative Sprachen sind für Menschen, die ihre Gedanken rechtzeitig erledigen wollen.": Nach meiner Erfahrung ist dies nicht wahr. Mit funktionalen Sprachen kann ich Dinge schneller erledigen. Der imperative Stil ist viel ausführlicher und weniger aussagekräftig. Wenn ich eine imperative Sprache verwenden muss, brauche ich definitiv mehr Iterationen, bevor ich alles richtig mache.
Giorgio