Ist das Erlernen einer funktionalen Sprache ein besserer OOP-Programmierer? [geschlossen]


28

Als Java / C # / C ++ - Programmierer höre ich viel über funktionale Sprachen, habe aber nie die Notwendigkeit gefunden, eine zu lernen. Ich habe auch gehört, dass Sie aufgrund des höheren Denkens in funktionalen Sprachen ein besserer OOP / prozeduraler Sprachprogrammierer sind.

Kann das jemand bestätigen? Inwiefern verbessert es Ihre Programmierkenntnisse?

Was ist eine gute Wahl für das Erlernen einer Sprache mit dem Ziel, die Fähigkeiten in einer weniger anspruchsvollen Sprache zu verbessern?


3
Wenn Sie in C # codieren, kennen Sie bereits eine. LINQ ist eine ziemlich funktionale Sache.
SK-logic

Ich denke, OOP ist besser für die Modellierung realer Objekte.
Tulains Córdova

1
@ user61852 Die meisten OO-Entwurfsmuster modellieren nichts über Objekte des "realen Lebens", sondern tatsächlich sehr abstrakte Konzepte.
Andres F.

Seien Sie mehr als ein Java / C # (+ C ++) - Programmierer. Es gibt einen Unterschied zwischen einem gigantischen Schweizer Taschenmesser mit einer nicht ganz so kleinen Broschüre, die beschreibt, warum Sie Klinge X aus 40 auswählen, und einer Klinge, mit der Sie fast alles herausschneiden können, was Sie wollen, weil sie sowohl verdammt scharf als auch gerade gekrümmt ist Richtig, damit Sie die Schneidkraft ohne viel Nachdenken auf eine Vielzahl von Situationen anwenden können. (mit einem Flaschenöffner im Griff natürlich)
Erik Reppen

Antworten:


32

Grundsätzlich stimme ich der Antwort von FrustratedWithFormsDesign zu , aber Sie haben auch gefragt, wie das Erlernen des neuen Paradigmas zur Entwicklung der eigenen Fähigkeiten beiträgt. Ich kann einige Beispiele aus meiner eigenen Erfahrung nennen.

Seit ich funktionales Programmieren lerne, bin ich mir viel bewusster darüber im Klaren, mit welchen Konzepten ich natürlicher als "Objekte" (im Allgemeinen, wo Mutation Sinn macht) und welche natürlicher als unveränderliche "Werte" betrachtet werden (ich denke, es gibt einen wichtigen Unterschied) Ich möchte darauf eingehen, wo OO Sinn macht und wann FP Sinn macht, aber das ist nur meine Meinung.

Ich bemerke, wo mein Code Nebenwirkungen enthält, und ich bin vorsichtiger, diese Stellen zu isolieren, indem ich mehr von meinen Funktionen zu "reinen" Funktionen mache. Dies verbessert die Testbarkeit meines OO-Codes erheblich.

Ich bin mir der Zyklen in meiner Datendarstellung bewusster. (Ich glaube beispielsweise nicht, dass Sie in Haskell eine Funktion schreiben können, mit der eine verknüpfte Liste in eine doppelt verknüpfte Liste konvertiert werden kann. Sie bemerken also in dieser Sprache deutlich mehr Zyklen.) Durch das Vermeiden von Zyklen wird der Synchronisationsaufwand verringert Sie müssen eine Leistung erbringen, damit Ihre Datenstrukturen intern konsistent sind. Dies erleichtert die gemeinsame Nutzung dieser Strukturen zwischen Threads.

Ich verlasse mich eher auf Rekursion (die rekursiven Schleifenkonstrukte des Schemas sind etwas Schönes). Dijkstra hat in den Anmerkungen zur strukturierten Programmierung darauf hingewiesen, dass rekursive Algorithmen der mathematischen Induktion sehr direkt zugeordnet sind, was seiner Ansicht nach das einzige Mittel ist, um intellektuell zu beweisen, dass unsere Schleifen korrekt sind. (Ich schlage nicht vor, dass wir unseren Code korrekt nachweisen müssen, aber je einfacher wir es uns selbst machen, desto wahrscheinlicher ist es, dass unser Code korrekt ist.)

Ich verwende eher Funktionen höherer Ordnung. John Hughes 'Arbeit Why Functional Programming Matters . Es unterstreicht die Kompositionsfähigkeit, die Sie durch den Einsatz funktionaler Programmiertechniken erhalten, wobei Funktionen höherer Ordnung eine wichtige Rolle spielen.

Wie in Jettis Antwort angesprochen , werden Sie auch feststellen, dass viele FP-Ideen in neuere OO-Sprachen integriert werden. Ruby und Python bieten beide viele Funktionen höherer Ordnung. Ich habe gehört, dass LINQ als ein Versuch beschrieben wurde, Unterstützung für monadisches Verständnis in C # zu bringen. Sogar C ++ hat jetzt Lambda-Ausdrücke.


@Aidan: wrt lambdas in C ++ 0x, jedenfalls haben die neuen C ++ - Compiler sie schon eingebaut.
Matthieu M.

1
"Objekt" als "Objekt, das einen veränderlichen Zustand besitzt" ist sehr verbreitet, aber das Wertobjektmuster gibt es schon seit vielen Jahren.
Frank Shearar

@ Matthieu, danke, ich habe den Text aktualisiert, um das widerzuspiegeln.
Aidan Cully

@Frank: danke für den zeiger. Ich habe dies nicht in die Antwort aufgenommen, aber der Hauptgrund, warum ich Werte in Objekte umwandeln muss, liegt in der Unterscheidung zwischen s / w-Objektschnittstellen (deren Eigentümer Objekte sind) und Operationen (in denen die Beziehungen zwischen Objekten größer sind) primär als die Objekte selbst). 1 + 2ist mathematisch äquivalent zu 2 + 1, wird aber 1.+(2)anders implementiert als 2.+(1). Es gibt eine Reihe von SW-Problemen, die unter Verwendung von Operationen natürlicher verstanden werden können als unter Verwendung von Objektschnittstellen.
Aidan Cully

1
@Aidan Haben Sie William Cooks "Über das Verständnis der Datenabstraktion, überarbeitet" gelesen? Es befasst sich mit den Unterschieden zwischen Objekten und ADTs, auf die Sie hinweisen.
Frank Shearar

32

Ich würde nicht sagen, dass Sie damit garantiert ein besserer OOP-Programmierer werden, aber es wird Sie in eine neue Denkweise einführen, und das könnte Sie beim Lösen von Problemen im Allgemeinen besser machen, nicht nur in Bezug auf OOP.


3
Angesichts der Tatsache, dass Objekte Funktionen höherer Ordnung sind, stellte ich fest, dass das Erlernen von FP-Inhalten direkt bei meiner OOP hilfreich war. Es ist, wie Sie sagen, allgemeiner anwendbar / hilfreich.
Frank Shearar

12

Das Erlernen einer funktionalen Sprache - für mich Lisp - hilft wirklich beim Erstellen paralleler Anwendungen. Funktionale Methoden (zustandsbasiert, keine Nebenwirkungen) sind viel einfacher zu synchronisieren und Thread-sicherer zu machen, da sie nur von ihrer Eingabe abhängen. Das bedeutet, dass Sie für einen bestimmten Codebereich nur die von Ihnen übergebenen Parameter überwachen müssen. Dies erleichtert auch das Debuggen.


Sie werden feststellen, dass es auch bei Threading-Bibliotheken hilfreich ist, die dazu neigen, reine Funktionen als ihre Aufgaben zu erwarten. Es kann auch indirekt helfen. Es gibt Stellen, an denen ich OO-Code in einer Art "funktionalem Stil" schreibe, wo es einen "Besitzparameter" gibt, der eine implizite Sperre für eine Reihe von Objekten aufweist, auf die er verweist und die von der Funktion verwendet werden . Solange Sie Ihre Erwartungen dokumentieren (und Unit-Tests durchführen), können Sie mit wenigen Sperrproblemen besseren Multithread-Code erhalten. Und ein paar explizite Sperren.

Ich habe noch nie davon gehört, dass Prolog eine funktionale Sprache genannt wird. Wenn ich genug schaue, kann ich vage sehen, wie (Teile von) Prolog bei FP helfen könnten.
Frank Shearar

1
Prolog ist keine funktionale Sprache. Es ist eine logische Sprache. Wenn Sie eine Prolog- ähnliche Logiksprache wollen , die auch funktionale Programmierung integriert, können Sie Mercury ausprobieren . Warnung: Es wird Ihr Gehirn ein wenig verletzen, auch wenn Sie Prolog bereits kennen.
NUR MEINE STELLUNGNAHME

@NUR MEINE STELLUNGNAHME: Ja, ich glaube, Sie haben Recht. Ich muss mehr über funktionale Sprachen lernen!
Michael K

1
@ Moz: Ja, ich wünschte, Java hätte Lambdas. Anonyme ThreadObjekte sind ... ungeschickt.
Michael K

9

Das Erlernen eines anderen Programmierparadigmas verbessert Ihre Programmierkenntnisse im Allgemeinen. Programmieren ist im Grunde genommen eine Problemlösung, wenn es sich nicht um akademische Forschungsarbeiten handelt (und selbst dann oft). Mit einem Wort nachdenken. Die verschiedenen Paradigmen sind unterschiedliche Denkweisen über Probleme und deren Lösungen. Stellen Sie sich das also nicht einfach als "Lernen einer funktionalen Sprache" vor. Betrachten Sie es als "Lernen, wie man Probleme und ihre Lösungen auf andere Weise betrachtet". Dann werden Sie die Vorteile des Lernens einer Sprache sehen, auch wenn Sie sie nie wirklich benutzen.

Um Ihre spezielle Frage zu beantworten, war ich früher ein C ++ - Programmierer (früher, bevor es einen Standard für C ++ gab). Ich folgte allen üblichen Dingen mit Objekten, deren Zustand durch Methoden usw. usw. usw. manipuliert wurde. Dann stolperte ich über Haskell und lernte (viel) davon. (Ich glaube, niemand lernt Haskell wirklich.) Die Übung schien zu der Zeit etwas verschwendet zu sein, bis einer meiner Kollegen, der meiner Gruppe zugeordnete Tester, einen Kommentar machte, dass mein Code einfacher zu testen sei.

Was passiert war, war, dass ich anfing, meine Objekte immer unveränderlicher zu machen. Klassen mit komplexen veränderlichen Zuständen wurden durch Klassen ersetzt, die sich selbst mit Änderungen geklont hatten und die neuen Objekte zurückgaben. Gemeinsam genutzte Objekte wurden durch Objekte mit einer Schreib-Kopie-Semantik ersetzt (wodurch die Illusion von vielen Objektklonen ohne Speicheraufwand entstand). Die Funktionen hatten keine Nebenwirkungen, es sei denn, dies ist unbedingt erforderlich. Die rein mathematische Definition von "Funktion" war immer mehr die Norm. All dies begann natürlich in meinem Code zu passieren - kein bewusster Gedanke wurde involviert - als ich mehr und mehr den funktionalen Programmierraum erkundete.

Jetzt ist es mein Ziel, alle zwei Jahre mindestens ein neues Programmierparadigma zu erlernen (auch wenn es sich nur um ein geringfügiges Erweiterungsparadigma wie AOP handelt) und mindestens zwei neue Sprachen in jedem Paradigma (eine so rein wie möglich, eine weitere hybride / praktische Sprache) ). Jeder hat mir neue intellektuelle Werkzeuge gegeben, mit denen ich alle meine Programme in jeder Sprache anwenden kann, so dass die Zeit, die ich damit verbracht habe, sie zu lernen, meiner Meinung nach nicht einmal ein bisschen verschwendet wurde.


3

Ich habe es schon einmal gesagt und ich sage es noch einmal. Das Erlernen von funktionalen Sprachen hat definitiv mein C # verbessert. Es half mir, Lambdas zu verstehen (und half mir, sie zu lieben). Mir wurde auch klar, wie sehr ich funktionale Programmierung (F #) bevorzuge, wenn ich mit asynchronen Operationen arbeite!


3

Maschinencode ist nichts weiter als eine Liste von Nebenwirkungen - Befehle, die direkt vom Prozessor ausgeführt werden. Die Nebenwirkungen in C sind unterschiedlich. Statt mit den Registern und der physischen Hardware umzugehen, müssen Sie sich mit einer Reihe von Abstraktionen befassen und den Compiler die ganze Drecksarbeit machen lassen. Mit C können Sie Ihre Nebenwirkungen auch in Schleifen und if then-Anweisungen strukturieren. C ++ verbessert C, indem es der Sprache OOP und einige dringend benötigte Funktionen hinzufügt. Java und C # fügen eine Garbage Collection hinzu, und Python fügt dynamische Typisierung hinzu.

Selbst mit all diesen Funktionen - dynamisches Tippen, Garbage Collection usw. - basieren Programme in diesen Sprachen immer noch ausschließlich auf Nebenwirkungen. Funktionale Programmiersprachen wie Scheme, Clojure, Haskell und ML sind etwas völlig anderes. Diese Sprachen sind der Mathematik näher als dem Maschinencode. Statt Nebenwirkungen zu verwenden, übergeben Sie Werte an Funktionen.

Was ist eine gute Wahl für das Erlernen einer Sprache mit dem Ziel, die Fähigkeiten in einer weniger anspruchsvollen Sprache zu verbessern?

Ich empfehle Schema , es ist minimal und es wurde in den alten Einführungskursen des MIT verwendet. Die anderen funktionalen Programmiersprachen sind viel schwerer zu lernen. Clojure bringt alle Feinheiten von Java mit, ML bringt ein kompliziertes statisches Typensystem mit, Haskell wird manchmal als akademische Sprache bezeichnet - es ist nicht ideal für Anfänger und so weiter. Schema auf der anderen Seite ist leicht zu lernen und zu verstehen.

Inwiefern verbessert es Ihre Programmierkenntnisse?

Fast alle höheren Programmiersprachen haben Funktionen und Rekursionen - die Konzepte, auf denen die funktionale Programmierung basiert. Als solches sollten Ihre FP-Kenntnisse fast überall hilfreich sein. Wenn Sie jedoch wirklich funktional programmieren möchten, sollten Sie eine Sprache verwenden, die natürlich und effizient ist, anstatt zu versuchen, das Sprachdesign eines anderen nach Ihren Wünschen zu gestalten Sie sollten eine funktionale Programmiersprache verwenden, um eine funktionale Programmierung durchzuführen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.