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?
Antworten:
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.
quelle
1 + 2
ist mathematisch äquivalent zu2 + 1
, wird aber1.+(2)
anders implementiert als2.+(1)
. Es gibt eine Reihe von SW-Problemen, die unter Verwendung von Operationen natürlicher verstanden werden können als unter Verwendung von Objektschnittstellen.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.
quelle
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.
quelle
Thread
Objekte sind ... ungeschickt.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.
quelle
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!
quelle
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.
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.
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.
quelle