Functional Programming vs. OOP [geschlossen]

93

Ich habe in letzter Zeit viel darüber gesprochen, funktionale Sprachen wie Haskell zu verwenden. Was sind einige der großen Unterschiede, Vor- und Nachteile der funktionalen Programmierung gegenüber der objektorientierten Programmierung?

GSto
quelle
27
Einer lehnt einen anderen nicht ab.
mbq
1
@mbq ich verstehe, dass sie sich nicht gegenseitig ausschließen, aber ich wollte nur versuchen, ein besseres Verständnis für den Unterschied der beiden Ansätze zu bekommen.
GSto
Gute Frage. Darüber habe ich mich auch schon gewundert.
JohnFx
Funktionale Programmierung und objektorientierte Programmierung sind orthogonal zueinander. Sie können beide in derselben Sprache haben. Beispiele: Scala, F #, OCaml usw. Vielleicht meintest du funktional oder imperativ, wie Jonas vorgeschlagen hat ?
Fehlender Faktor
4
Die wirkliche Antwort ist - es gibt kein "Versus" zwischen ihnen. Schauen Sie sich diese Frage bei StackOverflow an .
Fehlender Faktor

Antworten:

67

Ich würde sagen , dass es mehr ist Functional Programming vs Imperative Programmierung .

Der größte Unterschied besteht darin, dass es bei der imperativen Programmierung um den Kontrollfluss und bei der funktionalen Programmierung um den Datenfluss geht . Eine andere Art zu sagen ist, dass die funktionale Programmierung nur Ausdrücke verwendet , während bei der imperativen Programmierung sowohl Ausdrücke als auch Anweisungen verwendet werden.

Zum Beispiel sind Variablen und Schleifen in der imperativen Programmierung beim Umgang mit Zuständen üblich, während in der funktionalen Programmierung der Zustand über die Parameterübergabe behandelt wird, wodurch Nebenwirkungen und Zuweisungen vermieden werden.

Imperativer Pseudocode für eine Funktion zur Berechnung der Summe einer Liste (die Summe wird in einer Variablen gespeichert):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Funktionaler Pseudocode für dieselbe Funktion (die Summe wird als Parameter übergeben):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Ich empfehle den Vortrag Zähmungseffekte mit funktionaler Programmierung von Simon Peyton-Jones, um eine gute Einführung in funktionale Konzepte zu erhalten.

Jonas
quelle
12
Sie sollten erwähnen, dass die funktionale Version rekursiv ist und daher optimiert wurde, um Stapelüberläufe zu vermeiden. (Einige Leute könnten die Rekursion sehen und denken, dass die funktionale Programmierung deswegen schlecht ist)
Alternative
3
+1 zur Beschreibung des wichtigsten Aspekts von Imperativ vs. Funktional: Kontrollfluss vs. Datenfluss. Eine Sache, die ich hinzufügen muss, ist, dass sich das Funktionsparadigma und das OO-Paradigma nicht gegenseitig ausschließen. Sie können das OO-Paradigma verwenden, um die Interaktion zwischen Objekten (Daten) zu modellieren, und das Funktionsparadigma, um dieses Objekt zu transformieren (zu manipulieren).
Lie Ryan
1
Interessanterweise können Sie auch Daten als Steuerung und Steuerung als Daten modellieren, um sie zu mischen. FP kann Pfeile und Funktionen erster Ordnung verwenden, um den Kontrollfluss weiterzuleiten und wie Daten zu bearbeiten. OOP verwendet verschiedene Entwurfsmuster, um Objekte zum Ändern des Steuerungsflusses zu verwenden.
CodexArcanum
Ich denke, es ist auch erwähnenswert, dass der Hauptunterschied nicht darin besteht, dass Sie dasselbe Programm schreiben, sondern dass Sie Ihre Schleifen mit rekursiven Methoden aufrufen. es ist viel größer als das
sara
Ihr Funktionsbeispiel nutzt den Parameter-Pattern-Matching. Dies gilt nicht nur für die funktionale Programmierung, auch funktionale Programme können Monaden und sogar imperativartige Konstrukte verwenden, ohne dass jeder iterative Algorithmus notwendigerweise als rekursiver Algorithmus formuliert werden muss.
Dai
16

Die funktionale Programmierung basiert auf einem deklarativen Modell und wurzelt in der Lambda-Rechnung. Es bietet viele großartige Konzepte, die aus wichtigeren Sprachen wie C ++ und C # entlehnt werden können.

Einige Beispiele sind referentielle Transparenz, Lambda-Funktionen, erstklassige Funktionen, verzögerte und eifrige Bewertung und Unveränderlichkeit.

Wenn für nichts anderes das Erlernen der funktionalen Programmierung für die darin enthaltenen Konzepte nützlich ist. Es wird die Art und Weise verändern, wie Sie programmieren und über das Programmieren nachdenken. Und ich würde vermuten, dass die funktionale Programmierung in Zukunft genauso wichtig sein wird wie die objektorientierte Programmierung.

Zunächst können Sie eine rein funktionale Sprache wie Haskell oder eine hybride Sprache wie F # verwenden .

Die meisten guten Universitäten decken funktionale Programmierung ab, und wenn Sie zur Schule gehen, würde ich Ihnen dringend empfehlen, diesen Kurs zu belegen.


Was sind einige der großen Unterschiede, Vor- und Nachteile der funktionalen Programmierung gegenüber der objektorientierten Programmierung?

Eine gut objektorientierte Programmierung ist nett, da Sie damit Ihr komplexes Problem in Hierarchien modellieren können, um das Problem zu vereinfachen. Es wird jedoch sehr schwierig, wenn Sie anfangen, Multi-Thread-Programmierung bei der Verwendung veränderlicher Objekte in Betracht zu ziehen. In solchen Fällen müssen Synchronisationsobjekte häufig verwendet werden, und es ist nahezu unmöglich, eine große Anwendung zu perfektionieren.

Hier kommt die funktionale Programmierung ins Spiel. Aufgrund von Unveränderlichkeit vereinfacht die funktionale Programmierung Multithread-Programme wirklich. Es macht es fast trivial einfach, etwas zu parallelisieren, wenn Sie wissen, dass bei einer Eingabe von X für eine Funktion immer Y ausgegeben wird. Außerdem wissen Sie, dass eine Variable (oder ein Wert in der funktionalen Programmierung) während der Verwendung eines anderen Threads nicht geändert werden kann.

Brian R. Bondy
quelle
2
Um es klar auszudrücken: Schema ist keineswegs eine reine Funktionssprache.
Jonathan Sterling
5
Ihr vorletzter Absatz ist komplett bs. OO bereitet beim Multithreading keine Probleme, die Veränderbarkeit jedoch. Sie scheinen imperative Programmierung mit objektorientierter Programmierung zu verwechseln. Ist das der Fall?
Fehlender Faktor
5
@missingfaktor: Nein ich verwechsle die Konzepte nicht. Ein Objekt verfügt normalerweise über Accessoren, Modifikatoren, Datenelemente und Elementfunktionen. Ja, nicht alle Objekte müssen Modifikatoren haben, und Sie können sie als unveränderlich implementieren. Wenn Sie sich jedoch ein beliebiges OO-Programm ansehen, wird es mit ziemlicher Sicherheit mehrere Objekte enthalten, die Modifikatoren haben und dennoch von mehreren Threads verwendet werden. Dh in einem OOP-Paradigma ist es ziemlich selten, dass alles unveränderlich ist.
Brian R. Bondy
Sie sollten die Antworten auf diese Frage lesen: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/…
missingfaktor
Überprüfen Sie auch Frank Shearars Antwort hier: programmers.stackexchange.com/questions/12423/…
missingfaktor
8

(Diese Antwort wird von einer Antwort auf eine geschlossene Frage bei StackOverflow übernommen .)

Einer der großen Unterschiede zwischen funktionaler Programmierung und objektorientierter Programmierung besteht darin, dass jeder einzelne in einer anderen Art der Softwareentwicklung besser ist:

  • Objektorientierte Sprachen sind gut, wenn Sie eine feste Anzahl von Operationen für Dinge ausführen und wenn sich Ihr Code weiterentwickelt, fügen Sie hauptsächlich neue Dinge hinzu. Dies kann erreicht werden, indem neue Klassen hinzugefügt werden, die vorhandene Methoden implementieren, und die vorhandenen Klassen in Ruhe gelassen werden.

  • Funktionale Sprachen sind gut, wenn Sie einen festen Satz von Dingen haben und wenn sich Ihr Code weiterentwickelt, fügen Sie in erster Linie neue Operationen für vorhandene Dinge hinzu. Dies kann erreicht werden, indem neue Funktionen hinzugefügt werden, die mit vorhandenen Datentypen rechnen, wobei die vorhandenen Funktionen in Ruhe gelassen werden.

Wenn die Evolution in die falsche Richtung geht, haben Sie Probleme:

  • Das Hinzufügen einer neuen Operation zu einem objektorientierten Programm erfordert möglicherweise das Bearbeiten vieler Klassendefinitionen, um eine neue Methode hinzuzufügen.

  • Das Hinzufügen einer neuen Art von Dingen zu einem Funktionsprogramm erfordert möglicherweise das Bearbeiten vieler Funktionsdefinitionen, um einen neuen Fall hinzuzufügen.

Dieses Problem ist seit vielen Jahren bekannt. 1998 nannte Phil Wadler es das "Ausdrucksproblem" . Obwohl einige Forscher der Ansicht sind, dass das Expressionsproblem mit solchen Sprachmerkmalen wie Mixins angegangen werden kann, hat eine allgemein akzeptierte Lösung noch nicht den Mainstream erreicht.

Norman Ramsey
quelle
Ich liebe deine Antwort, Wort der Weisheit hier. Ich habe es vor ein paar Monaten kennengelernt und nur 30 Minuten damit verbracht, es speziell zu suchen, da ich es nicht als Lesezeichen gespeichert habe. Nur die beste Erklärung für OOP vs FP für diejenigen, die den Vorteil des Verstehens von Konzepten statt Techniken verstehen. Das Papier über das Ausdrucksproblem ist auch fantastisch. Vielen Dank für Ihre Einsicht, Ihre Antwort ist meiner Meinung nach sehr unterschätzt.
tobiak777
4

Es gibt keine wirklichen Verse. Sie können sich perfekt ergänzen. Es gibt FP-Sprachen, die OOP unterstützen. Die Communities unterscheiden sich jedoch in der Art und Weise, wie sie mit Modularität umgehen.

Benutzer von FP-Sprachen neigen dazu, Modularität durch mathematische Gesetze zu erreichen. Und bevorzugen Sie Beweise, die die Einhaltung ihrer Gesetze belegen.

In imperativen OOP-Fällen neigen Benutzer dazu, das Verhalten des Objekts in Testfällen zu erfassen, die erneut ausgeführt werden können, wenn sich das Objekt geändert hat, und auf diese Weise Modularität erzielen.

Es ist nur ein kleiner Aspekt, aber ich denke, es ist erwähnenswert.

Edgar Klerks
quelle
2

Eine Analogie:

Sie erhalten eine Bewerbung. Sie geben Ihren Namen, Ihre Kontaktinformationen und Ihren Arbeitsverlauf ein. Wenn Sie fertig sind, haben Sie keine leere Bewerbung mehr.

Stellen Sie sich stattdessen vor, Sie überziehen sie vor dem Schreiben mit einem klaren Blatt Zellophan. Du schreibst deinen Namen. Sie fügen ein weiteres Blatt Zellophan hinzu. Sie schreiben Ihre Kontaktinformationen. Mehr Zellophan. Sie schreiben Ihre Arbeitsgeschichte. Wenn Sie fertig sind, haben Sie noch die leere Anwendung unberührt. Sie haben auch drei Blätter Cellophan, von denen jedes den Effekt einer einzelnen diskreten Änderung erfasst hat.

Ersteres (OOP) befasst sich mit der Idee, Dinge an Ort und Stelle zu ändern, während letzteres (FP) dies meidet. Beides sind Paradigmen des Staatsmanagements. Beide können mit unterschiedlichen Strategien den Effekt des Abschlusses einer Bewerbung erfassen. OOP ändert das Startinstrument direkt, während FP das Vorherige überlagert , um das Erscheinungsbild der Änderung zu beeinflussen .

Mario T. Lanza
quelle
schöne analogie, danke !! würde es Ihnen (wenn möglich) etwas ausmachen, diese Analogie auf die Vor- und Nachteile dieser beiden Ansätze auszudehnen?
Rahul Agarwal