Ein YouTube - Video war ich gerade erklärte die Unterschiede zwischen Imperativen und Funktionale Programmierung durch den Nachweis , wie die Zahlen aus 1
zu 10
jeweils in Java und in Haskell aufsummiert.
In Java müssen Sie jeden Schritt explizit angeben und das Ergebnis jedes Schritts einer Variablen zuweisen - etwa wie folgt
int total = 0;
for (int i = 1; i <= 10; i++){
total = total + i;
}
return total;
In Haskell kann man einfach sagen:
sum(1..10)
Meine Frage ist: Im Hintergrund einer funktionalen Sprache ist offensichtlich etwas los, und dass etwas eine Art imperativer Prozess sein muss. Es scheint, dass funktionale Sprachen wirklich nur eine Art von APIs für imperative Sprachen sind. Zum Beispiel kann ich einen Teil einer funktionalen Sprache erstellen, indem ich eine Methode sum(int start, int end)
in Java definiere. Habe ich genau dort wirklich eine neue Art von Sprache erstellt oder habe ich nur eine Reihe von imperativen Methodenaufrufen definiert, die imperative Anweisungen vor Ihnen verbergen?
Ich hoffe, es ist klar, was ich nur schwer verstehen kann.
quelle
Antworten:
Wenn wir den syntaktischen Zucker auf der Vorderseite und die Codegenerierung auf der Rückseite abziehen und vergleichen, was dazwischen passiert, wenn der Quellcode in einen laufenden Code für zwingende Sprachen wie C oder Java mit funktionalen Sprachen wie ML oder OCaml konvertiert wird, werden wir im Allgemeinen feststellen die folgenden Unterschiede in was, warum und wie.
Veränderlich gegen unveränderlich
Bei der funktionalen Programmierung werden in der Regel unveränderliche Werte verwendet, sodass wir uns keine Sorgen machen müssen, wenn sich ein Wert außerhalb unserer aktuellen Funktion ändert. Bei richtiger Anwendung werden alle Probleme im Zusammenhang mit Nebenwirkungen beseitigt .
Fokus: Daten versus Funktion.
Wenn man an eine zwingende Codierung denkt, denkt man zuerst an Datenstrukturen und dann an die Methoden, die sie benötigen. Wenn man mit funktionaler Programmierung arbeitet, denkt man zuerst an die benötigten Funktionen und stellt dann die benötigten Datentypen her . Die meisten Datentypen sind entweder Lazy List (Think Stream oder Infinite List) oder diskriminierte Gewerkschaften . Wenn die diskriminierte Vereinigung rekursiv ist, haben Sie sofort einen Baum oder eine Grafik erstellt, ohne den gesamten Laufcode schreiben zu müssen.
Generika / Parametrischer Polymorphismus
Dieser ist interessant, und wenn ich meine Fakten richtig habe, wurde er mit funktionaler Programmierung erfunden und dann in die imperative Programmierung übertragen. Wenn Sie Generika mögen, bedanken Sie sich bei den Designern der funktionalen Sprache.
Referenzielle Transparenz / Parallelisierung
Aufgrund der referenziellen Transparenz kann Funktionscode einfacher auf paralleles Rechnen portiert werden .
Funktion / Komposition höherer Ordnung
Da Funktionen neue Funktionen erstellen und Funktionen zurückgeben können, ist das Erstellen neuer Funktionen auf anderen Funktionen genauso einfach wie das Erstellen neuer Ausdrücke, anstatt ganz neue Methoden zu schreiben. Dies führt zu Morphismen, die sehr nützlich sind, wenn das Problem, das Sie lösen, mit Mathematik erklärt werden kann. Mit der funktionalen Programmierung ist es viel einfacher, Set-Transformationen durchzuführen, an SQL und Updates zu denken. Wie Wandering Logic feststellte, zeichnen sich hier funktionale Programmiersprachen aus.
Typisierung: Statisch versus Inferenz .
Da die Typen abgeleitet werden, anstatt vom Programmierer während des Schreibens festgelegt zu werden, können mehr Überprüfungen durchgeführt werden, um die Richtigkeit des Codes sicherzustellen, und häufig werden die Funktionen generisch gemacht, anstatt von einem festgelegten Typ zu sein.
Pattern Matching vs switch-Anweisung
Wenn Sie Matching mit diskriminierten Gewerkschaften kombinieren, wird Ihr Matching überprüft, um sicherzustellen, dass Sie jedes Ergebnis abgedeckt haben. Wie oft hatten Sie einen Laufzeitfehler, weil Sie einen Fall mit einer switch-Anweisung verpasst haben.
quelle
Eine funktionale Programmierung Sprache ist bemerkenswert für das, was es verbietet . Es verbietet das Ändern einer vorhandenen Variablen oder Datenstruktur. Sie können in einigen wichtigen Programmiersprachen in einem "funktionalen Stil" programmieren, aber die Sprache schützt Sie nicht davor, versehentlich eine vorhandene Variable oder Datenstruktur zu ändern. Hier ist zum Beispiel eine rekursive, funktionale Version von
sum
in Java:Funktionale Programmiersprachen zeichnen sich dadurch aus, dass sie alle "erstklassige" Funktionen haben. Das heißt: Eine Funktion kann wie eine Ganzzahl oder eine Datenstruktur als Wert verwendet werden. Einige imperative Sprachen haben auch erstklassige Funktionen (insbesondere C und C ++), aber in Java müssen Sie es mit einem Objekt mit einer einzigen Methode (normalerweise aufgerufen
apply()
oder so) fälschen. Mit erstklassigen Funktionen können wir diesum
Funktion auf a verallgemeinern Funktion, die jeden Bediener reduziert:Wenn ich in einer funktionalen Programmiersprache schreiben würde, würde ich wissen, dass jede Funktion wirklich eine Funktion ist (sie gibt jedes Mal den gleichen Wert zurück, wenn sie mit denselben Parametern aufgerufen wird), also würde ich das wissen in:
total1
undtotal2
haben den gleichen Wert (so könnte ich zum Beispiel den zweiten Aufruf von optimierensum
), während ich in einer imperativen Programmiersprache keine Ahnung habe, obReallyStrangeOperator(1,2)
jedes Mal der gleiche Wert zurückgegeben wird oder nicht.quelle