Je mehr Funktionen ich programmiere, desto mehr kommt eine zusätzliche Abstraktionsebene hinzu, die so aussieht, als würde die Ebene einer Zwiebel die vorherigen Ebenen umfassen.
Ich weiß nicht, ob dies zutrifft, und kann jemand erklären, wie funktional eine der Prinzipien ist oder nicht: Kapselung, Abstraktion, Vererbung, Polymorphismus
Ich denke, wir können alle sagen, ja, es hat die Kapselung über Tupel, oder zählen Tupel technisch als Faktum der "funktionalen Programmierung" oder sind sie nur ein Nutzen der Sprache?
Ich weiß, dass Haskell die "Schnittstellen" -Anforderung erfüllen kann, bin mir aber auch nicht sicher, ob es sich bei der Methode um eine funktionale Tatsache handelt? Ich vermute, dass die Tatsache, dass Funktoren eine mathematische Basis haben, man sagen könnte, dass diese eine definitive Erwartung von Funktionalität sind, vielleicht?
Bitte erläutern Sie, wie funktional Ihrer Meinung nach die 4 Prinzipien von OOP erfüllt oder nicht erfüllt.
Bearbeiten: Ich verstehe die Unterschiede zwischen dem funktionalen Paradigma und dem objektorientierten Paradigma sehr gut und stelle fest, dass es heutzutage viele multiparadigmische Sprachen gibt, die beides können. Ich bin wirklich nur auf der Suche nach Definitionen, wie direkt fp (denke puristisch, wie haskell) eines der 4 aufgelisteten Dinge tun kann oder warum es keines von ihnen tun kann. dh "Kapselung kann mit Verschlüssen erfolgen" (oder wenn ich mich in dieser Annahme irre, geben Sie bitte an, warum).
quelle
Antworten:
Funktionale Programmierung liegt nicht über OOP. Es ist ein völlig anderes Paradigma. Es ist möglich, OOP in einem funktionalen Stil durchzuführen (F # wurde genau für diesen Zweck geschrieben), und am anderen Ende des Spektrums gibt es Dinge wie Haskell, die die Prinzipien der Objektorientierung explizit ablehnen.
Sie können die Kapselung und Abstraktion in jeder Sprache ausführen, die für die Unterstützung von Modulen und Funktionen fortgeschritten ist. OO bietet spezielle Mechanismen für die Verkapselung, die OO jedoch nicht inhärent sind. Der Punkt von OO ist das zweite Paar, das Sie erwähnt haben: Vererbung und Polymorphismus. Das Konzept ist formal als Liskov-Substitution bekannt, und ohne Sprachunterstützung für objektorientierte Programmierung ist es nicht zu bekommen. (Ja, es ist möglich, es in einigen Fällen zu fälschen, aber Sie verlieren viele der Vorteile, die OO auf den Tisch bringt.)
Die funktionale Programmierung konzentriert sich nicht auf die Liskov-Substitution. Es konzentriert sich auf die Erhöhung der Abstraktionsebene und auf die Minimierung der Verwendung von veränderlichen Zuständen und Routinen mit "Nebenwirkungen", was ein Begriff ist, den funktionale Programmierer gerne verwenden, um Routinen zu erstellen, die tatsächlich etwas tun (anstatt einfach etwas zu berechnen) unheimlich. Aber auch hier handelt es sich um völlig separate Paradigmen, die je nach Sprache und Können des Programmierers zusammen verwendet werden können oder nicht.
quelle
Ich finde die folgende Intuition nützlich, um OOP und FP zu vergleichen.
Anstatt FP als Obermenge von OOP zu betrachten, stellen Sie sich OOP und FP als zwei alternative Betrachtungsweisen für ein ähnliches zugrunde liegendes Berechnungsmodell vor, in dem Sie Folgendes haben:
In OOP wird dies von erfasst
In FP wird dies von erfasst
Mit dieser Interpretation kann ein Objekt als eine Sammlung von Abschlüssen (seine Methoden) angesehen werden, die alle dieselben nicht lokalen Variablen erfassen (die Mitgliedsvariablen des Objekts, die allen Abschlüssen in der Sammlung gemeinsam sind). Diese Ansicht wird auch dadurch gestützt, dass in objektorientierten Sprachen Verschlüsse häufig als Objekte mit genau einer Methode modelliert werden.
Ich denke, die unterschiedlichen Sichtweisen ergeben sich aus der Tatsache, dass die objektorientierte Sicht auf die Objekte (die Daten) zentriert ist, während die funktionale Sicht auf die Funktionen / Abschlüsse (die Operationen) zentriert ist.
quelle
Es hängt davon ab, wen Sie nach einer Definition von OOP fragen. Wenn Sie fünf Personen fragen, erhalten Sie wahrscheinlich sechs Definitionen. Wikipedia sagt :
Wenn also jemand eine sehr eindeutige Antwort gibt, nehmen Sie sie mit einem Körnchen Salz.
Wie gesagt, es ist ein gutes Argument gemacht werden, dass, ja, FP ist ein Superset der OOP als Paradigma. Insbesondere Alan Kays Definition des Begriffs objektorientierte Programmierung widerspricht dieser Auffassung nicht ( Kristen Nygaards jedoch ). Alles, was Kay wirklich interessierte, war, dass alles ein Objekt ist und dass die Logik durch das Weitergeben von Nachrichten zwischen Objekten implementiert wird.
Vielleicht interessanter für Ihre Frage: Klassen und Objekte können als Funktionen und Abschlüsse betrachtet werden, die von Funktionen (die gleichzeitig als Klassen und Konstruktoren fungieren) zurückgegeben werden. Dies kommt der prototypbasierten Programmierung sehr nahe, und tatsächlich ermöglicht JavaScript genau dies.
(Natürlich erlaubt JavaScript das Mutieren von Werten, was in der rein funktionalen Programmierung illegal ist, aber in einer strengen Definition von OOP auch nicht erforderlich ist.)
Die wichtigere Frage ist jedoch: Ist dies eine sinnvolle Klassifizierung von OOP? Ist es hilfreich, es als Teilmenge der funktionalen Programmierung zu betrachten? Ich denke, dass dies in den meisten Fällen nicht der Fall ist.
quelle
FP wie OO ist kein genau definierter Begriff. Es gibt Schulen mit unterschiedlichen, manchmal widersprüchlichen Definitionen. Wenn du nimmst, was sie gemeinsam haben, kommst du zu:
Funktionale Programmierung ist die Programmierung mit erstklassigen Funktionen
OO-Programmierung ist eine Programmierung mit Inklusionspolymorphismus in Kombination mit mindestens einer eingeschränkten Form von dynamisch aufgelöster Überladung. (Eine Randnotiz: In OO-Kreisen bedeutet Polymorphismus normalerweise Inklusionspolymorphismus , während FP-Schulen normalerweise parametrischen Polymorphismus bedeuten .)
Alles andere ist entweder an anderer Stelle vorhanden oder fehlt in einigen Fällen.
FP und OO sind zwei Werkzeuge zum Erstellen von Abstraktionen. Sie haben jeweils ihre eigenen Stärken und Schwächen (zum Beispiel haben sie eine andere bevorzugte Ausdehnungsrichtung im Ausdrucksproblem), aber keine ist an sich mächtiger als die andere. Sie können ein OO-System über einen FP-Kernel erstellen (CLOS ist ein solches System). Sie können ein OO-Framework verwenden, um erstklassige Funktionen abzurufen (siehe beispielsweise die Definition von Lambda-Funktionen in C ++ 11).
quelle
std::function
, denen sowohl Funktionszeiger als auch Lambdas zugeordnet werden können, ist eindeutig generisch und nicht objektorientiert. Dies ist nicht verwunderlich, da die begrenzte Marke des Polymorphismus (Subtyp-Polymorphismus) der Objektorientierung weniger stark ist als der parametrische Polymorphismus (sogar Hindley-Milner, geschweige denn das vollständige System F-Omega).Nein; OOP kann als eine Obermenge der prozeduralen Programmierung angesehen werden und unterscheidet sich grundlegend vom funktionalen Paradigma, weil der Zustand in den Instanzfeldern dargestellt ist. Im Funktionsparadigma sind die Variablen Funktionen, die auf die konstanten Daten angewendet werden, um das gewünschte Ergebnis zu erhalten.
Tatsächlich können Sie die funktionale Programmierung als Teilmenge von OOP betrachten. Wenn Sie alle Ihre Klassen unveränderlich machen, können Sie davon ausgehen, dass Sie eine Art funktionale Programmierung haben.
quelle
Antworten:
Wikipedia hat einen großartigen Artikel über funktionale Programmierung mit einigen der Beispiele, nach denen Sie fragen. @Konrad Rudolph hat bereits den Link zum OOP-Artikel bereitgestellt .
Ich denke nicht, dass ein Paradigma eine Supermenge des anderen ist. Es handelt sich um unterschiedliche Programmierperspektiven, und einige Probleme lassen sich besser aus einer Perspektive und andere aus einer anderen Perspektive lösen.
Ihre Frage wird durch alle Implementierungen von FP und OOP noch komplizierter . Jede Sprache hat ihre eigenen Macken, die für eine gute Antwort auf Ihre Frage relevant sind.
Zunehmend tangentiales Wandern:
Ich mag die Idee, dass eine Sprache wie Scala versucht, Ihnen das Beste aus beiden Welten zu bieten. Ich mache mir Sorgen, dass es Ihnen die Komplikationen beider Welten gibt.
Java ist eine OO-Sprache, aber in Version 7 wurde eine "Try-with-Resources" -Funktion hinzugefügt, mit der eine Art Abschluss imitiert werden kann. Hier imitiert es das Aktualisieren einer lokalen Variablen "a" in der Mitte einer anderen Funktion, ohne sie für diese Funktion sichtbar zu machen. In diesem Fall ist die erste Hälfte der anderen Funktion der Konstruktor ClosureTry () und die zweite Hälfte die Methode close ().
Ausgabe:
Dies kann nützlich sein, um einen Stream zu öffnen, in den Stream zu schreiben und ihn zuverlässig zu schließen, oder um einfach zwei Funktionen so zu koppeln, dass Sie nicht vergessen, die zweite Funktion aufzurufen, nachdem Sie einige Arbeiten zwischen ihnen ausgeführt haben . Natürlich ist es so neu und ungewöhnlich, dass ein anderer Programmierer den try-Block entfernen könnte, ohne zu bemerken, dass er etwas kaputt macht. Daher ist es derzeit eine Art Anti-Pattern, aber interessant, dass dies möglich ist.
Sie können jede Schleife in den meisten imperativen Sprachen als Rekursion ausdrücken. Objekte und Variablen können unveränderlich gemacht werden. Verfahren können geschrieben werden, um Nebenwirkungen zu minimieren (obwohl ich behaupten würde, dass eine echte Funktion auf einem Computer nicht möglich ist - die Zeit, die für die Ausführung benötigt wird, und die verbrauchten Prozessor-, Festplatten- und Systemressourcen sind unvermeidbare Nebenwirkungen). Einige funktionale Sprachen können dazu gebracht werden, viele, wenn nicht sogar alle objektorientierten Operationen auszuführen. Sie müssen sich nicht gegenseitig ausschließen, obwohl einige Sprachen Einschränkungen aufweisen (z. B. dass keine Aktualisierung von Variablen zulässig ist), die bestimmte Muster verhindern (z. B. veränderbare Felder).
Für mich sind die nützlichsten Teile der objektorientierten Programmierung das Ausblenden (Einkapseln) von Daten, das Behandeln von Objekten mit ähnlichen Eigenschaften (Polymorphismus) und das Sammeln Ihrer Daten und Methoden, die diese Daten gemeinsam verarbeiten (Objekte / Klassen). Vererbung mag das Flaggschiff von OOP sein, aber für mich ist sie der am wenigsten wichtige und am wenigsten genutzte Teil.
Die nützlichsten Teile der funktionalen Programmierung sind Unveränderlichkeit (Token / Werte anstelle von Variablen), Funktionen (keine Nebenwirkungen) und Abschlüsse.
Ich denke nicht, dass es objektorientiert ist, aber ich muss sagen, dass eines der nützlichsten Dinge in der Informatik die Fähigkeit ist, eine Schnittstelle zu deklarieren, und dass dann verschiedene Teile der Funktionalität und Daten diese Schnittstelle implementieren. Ich mag es auch, ein paar veränderbare Daten zu haben, mit denen ich arbeiten kann. Ich glaube, ich fühle mich in ausschließlich funktionalen Sprachen nicht so wohl, obwohl ich versuche, die Veränderbarkeit und die Nebenwirkungen in all meinen Programmdesigns zu begrenzen.
quelle