Warum die derzeitige Begeisterung für funktionale Programmierung? [geschlossen]


50

Ich habe in letzter Zeit viel Begeisterung für funktionale Programmiersprachen in Bezug auf Scala, Clojure und F # gehört. Ich habe kürzlich angefangen, Haskell zu studieren, um das FP-Paradigma zu lernen.

Ich liebe es, es macht wirklich Spaß und passt zu meinem mathematischen Hintergrund.

Aber wird es jemals wirklich wichtig sein? Offensichtlich ist es keine neue Idee.

Hier sind meine Fragen:

  1. Was hat zur jüngsten Begeisterung der FP beigetragen? Ist es nur Langeweile mit OO, oder hat sich etwas geändert, damit FP mehr gebraucht wird als zuvor?
  2. Ist dies ein Hinweis auf eine FP-Zukunft? Oder ist dies eine Modeerscheinung, wie objektorientierte Datenbanken?

Mit anderen Worten, kann mir jemand helfen zu verstehen, woher das kommt und wohin es führen könnte?


1
mögliches Duplikat von Functional Programming vs. OOP
Amir Rezaei

13
Kein Duplikat - das ist die Frage, warum die Leute plötzlich Aufhebens machen, da es keine neue Idee ist (während diese Frage mehr nach objektiven Unterschieden fragt).
Peter Boughton

2
Die Leute machen in letzter Zeit ein Theater wegen FP? Ich dachte, dass dies immer der Fall war, wenn sich eine Gruppe darüber aufregte, wie FP die imperative Programmwelt übernehmen wird.
Chris

1
Ich glaube, ich habe diese Frage auf StackOverflow schon einmal beantwortet .
Ken Bloom

1
Ja - FP war schon alt Ich glaube, als ich 1989 Scheme als Student in Columbia einsetzte. Es ist die glänzende neue Sache, denke ich.
Tim

Antworten:


33

Eine der Hauptinnovationen in FP, die zu einer "Explosion" des Interesses geführt haben, sind Monaden.

Im Januar 1992 schrieb Philip Wadler einen Artikel mit dem Titel The Essence of Functional Programming, in dem Monaden in die funktionale Programmierung eingeführt wurden, um mit IO umzugehen.

Das Hauptproblem bei reinen, faulen und funktionalen Programmiersprachen war der Umgang mit E / A. Es ist eines der Mitglieder der "Awkward Squad" in der Programmierung, weil "Faulheit und Nebenwirkungen aus praktischer Sicht unvereinbar sind. Wenn Sie eine faule Sprache verwenden möchten, muss es so ziemlich eine rein funktionale Sprache sein; Wenn Sie Nebenwirkungen verwenden möchten, sollten Sie eine strenge Sprache verwenden. " Referenz

Das Problem mit IO vor Monaden war, dass es für Programme, die für irgendetwas nützlich waren, nicht möglich war, die Reinheit aufrechtzuerhalten. Mit E / A ist alles gemeint, was mit Zustandsänderungen zu tun hat, einschließlich der Ein- und Ausgabe vom Benutzer oder der Umgebung. In der reinen Funktionsprogrammierung ist alles unveränderlich, um Faulheit und Reinheit (frei von Nebenwirkungen) zu ermöglichen.

Wie lösen Monaden das Problem der IO? Nun, ohne zu viel über Monaden zu diskutieren, nehmen sie im Grunde genommen die "Welt" (die Laufzeitumgebung) als Eingabe für die Monade und erzeugen eine neue "Welt" als Ausgabe und das Ergebnis: Geben Sie IO a = Welt -> (a, Welt).

FP ist deshalb immer mehr in den Mainstream eingestiegen, weil das größte Problem, IO (und andere), gelöst wurde. Wie Sie wissen, wurde auch die Integration in vorhandene OO-Sprachen durchgeführt. LINQ ist Monaden, zum Beispiel durch und durch.

Für weitere Informationen empfehle ich das Lesen über Monaden und die in meiner Antwort genannten Artikel.


Sehr informativ, danke. Ich akzeptiere diese Antwort nicht, weil sie richtig ist und andere falsch liegen (ich habe mehrere positiv bewertet), sondern weil ich denke, dass sie die daraus resultierende Sichtbarkeit verdient.
Eric Wilson

Ein relevanteres Beispiel wäre jedoch type IO a = UI -> (a, UI)eine fantastische Antwort.
ChaosPandion

@ Richard: "Typ IO a = World -> (a, World)" klingt fast zu gut, um wahr zu sein (ich dachte, ich würde niemals Monaden bekommen). Ich vermute, Sie vergleichen LINQ mit Monaden, denn wenn Sie ein Lambda an einen LINQ-Operator übergeben, "sieht" das Lambda seine gesamte Umgebung, stimmt das?
Stefan Monov

@ Stefan: Es klingt ziemlich genau zu sagen, dass der Lambda seine Umgebung sieht, aber das ist mir nicht zu 100% klar. Ich zögere also zu antworten, bis ich selbst mehr darüber erfahre. Ich kann jedoch mit hundertprozentiger Sicherheit sagen, dass LINQ Monaden sind, weil die Entwickler dies schon oft gesagt haben. SelectMany entspricht exakt Bind in Haskell. Wenn Sie "Die Wunder der Monaden" nicht gelesen haben ( blogs.msdn.com/b/wesdyer/archive/2008/01/11/… ), kann ich es nur empfehlen ... es wird Ihnen zeigen, wie LINQ wirklich Monaden sind. Prost.
Richard Anthony Hein

1
@Job, siehe blogs.msdn.com/b/wesdyer/archive/2008/01/11/…, wie im obigen Kommentar angegeben.
Richard Anthony Hein

30

Eines der Hauptprobleme beim Programmieren traditioneller Sprachen wie C, Java, C #, Assembler usw. besteht darin, dass Sie eine umständliche Abfolge von Schritten ausführen müssen, um eine bestimmte Aufgabe auszuführen, da Sie zuerst alle Abhängigkeiten vorbereitet haben müssen und Ihre Abhängigkeiten früher

Ein Beispiel: Um A ausführen zu können, müssen B und C vorhanden sein, und B hängt von D und E ab, was zu so etwas wie führt

  • D
  • E
  • C
  • B
  • EIN

weil Sie die Zutaten vorbereiten müssen, bevor Sie sie verwenden können.

Funktionale Sprachen, besonders die faulen, stellen diese auf den Kopf. Indem Sie A sagen lassen, dass es B und C benötigt, und die Laufzeit der Sprache herausfinden lassen, wann B und C zu erhalten sind (was wiederum D und E erfordert), die alle ausgewertet werden, wenn A ausgewertet werden muss, können Sie sehr klein und präzise erstellen Bausteine, die zu kleinen und übersichtlichen Programmen führen. Die faulen Sprachen ermöglichen auch die Verwendung von unendlichen Listen, da nur die tatsächlich verwendeten Elemente berechnet werden und nicht die gesamte Datenstruktur gespeichert werden muss, bevor sie verwendet werden kann.

Der wirklich schöne Trick ist, dass dieser automatische "Oh, ich brauche ein B und ein C" Mechanismus skalierbar ist, da es - wie im sequentiellen Programm - keine Einschränkung gibt, wo und wann diese Auswertung stattfinden kann, so dass es am geschehen kann zur gleichen Zeit und sogar auf verschiedenen Prozessoren oder Computern.

Deshalb sind funktionale Sprachen interessant - denn der Mechanismus "Was ist zu tun, wenn" wird vom Laufzeitsystem übernommen, und der Programmierer muss ihn nicht manuell ausführen. Dies ist ein ebenso wichtiger Unterschied wie die automatische Garbage Collection für Java in C und einer der Hauptgründe, warum es einfacher ist, robuste, skalierbare Multithread-Software in Java als in C zu schreiben. skalierbare Multithread-Software in funktionalen Sprachen ...


3
Dies war natürlich 1950 der Fall.
Eric Wilson

1
@ FarmBoy, nicht wirklich, aber es ist heute.

5
Wie unterscheidet sich dies von der Abhängigkeitsinjektion?
Bill K

2
@Bill K, ausgezeichnete Beobachtung - ich hatte diese Verbindung nicht selbst hergestellt. Der Unterschied besteht darin, dass die zu injizierenden Objekte - zumindest in Java - eifrig und nicht träge bewertet werden. Sie können keine unendliche Liste einfügen.

1
@ Thorbjørn Ravn Andersen Ich bin mir nicht ganz sicher, warum eine unendliche Liste nützlich wäre. Können Sie tatsächlich eine Summe von Operationen vom Typ (unendliche Liste) ausführen? Scheint sehr unwahrscheinlich. Ansonsten klingt es nur so, wie Java Iteratoren verwendet. Sie codieren den Iterator nur so, dass er die Objekte nur instanziiert, wenn Sie danach fragen - nicht ganz unendlich, aber endlos (es gibt einen großen Unterschied, wie? )
Bill K

21

In den späten 80ern / frühen 90ern wurden Computer leistungsfähig genug für OOP im Smalltalk-Stil. Heutzutage sind Computer leistungsfähig genug für FP. FP programmiert auf einer höheren Ebene und ist daher oft - obwohl es angenehmer zu programmieren ist - nicht die effizienteste Art, ein bestimmtes Problem zu lösen. Aber Computer sind so schnell, dass es Ihnen egal ist.

Mehrkernprogrammierung kann mit rein funktionalen Programmiersprachen einfacher sein, da Sie gezwungen sind, Code zu isolieren, der den Status ändert.

Auch Programmiersprachengrenzen verschwimmen heute. Sie müssen ein Paradigma nicht aufgeben, wenn Sie ein anderes verwenden möchten. Sie können FP in den meisten gängigen Sprachen durchführen, sodass die Eintrittsbarriere niedrig ist.


6
Wollte eine Antwort hinzufügen, aber Sie haben meinen Punkt in Ihrem letzten Satz getroffen; Die funktionale Programmierung wird mit zunehmender Anzahl von Kernen in einer einzelnen Maschine immer häufiger. Der inhärente Mangel an Status erleichtert die mechanische Aufteilung funktionaler Programme auf Prozessoren (dh, wenn Sie ein rein funktionales Programm haben, kann ein Compiler die Parallelität theoretisch für Sie mit minimalem Aufwand erledigen, siehe youtube.com/watch? v = NWSZ4c9yqW8 für eine Diskussion der Datenparallelität).
Inaimathi

1
@ Inaimathi Ditto. Die funktionale Programmierung ist sehr skalierbar und daher auf Mehrkernarchitekturen sinnvoll.
EricBoersma

Beachten Sie, dass mein erster Kommentar geschrieben wurde, bevor die Antwort bearbeitet wurde, um eine zusätzliche Aussage zu enthalten.
Inaimathi

Das tut mir leid. Ich habe diesen Punkt einfach vergessen.
LennyProgrammers

Ist es wirklich allgemein anerkannt, dass funktionale Compiler nicht so optimierten Maschinencode erzeugen können wie ein OOPS? Ich kann mir keinen theoretischen Grund vorstellen, warum das wahr sein muss. und ich kann mir überlegen, wie fortgeschrittenere Optimierungen möglich sind als in einem OOPS.
Jeremy

7

Der heutige Bedarf an verteiltem Computing.

FP verwendet Funktionen als Bausteine, die keinen Status haben. Wenn Sie sie also n- mal mit denselben Parametern aufrufen, sollten Sie immer denselben Wert zurückgeben, da sie keine Nebenwirkungen haben.

Auf diese Weise können Sie die gleiche Funktion an mehrere Maschinen senden, um die Arbeiten parallel auszuführen.

Im OO-Paradigma ist dies etwas schwieriger, da die Bausteine ​​Objekte sind, die per Definition fast zustandsbehaftet sind. Wenn Sie dieselbe Methode mehrmals aufrufen, müssen Sie beim Synchronisieren der internen Daten vorsichtig sein, um eine Beschädigung der Daten zu vermeiden. Obwohl dies noch möglich ist, funktioniert das FP-Paradigma in einigen Szenarien, in denen Berechnungen verteilt werden müssen, besser als das OO.

Das Aufkommen von FP (und zu einem gewissen Grad von NoSQL) folgt den Geschichten über erstaunliche Computerergebnisse, die dazu führen, dass Hunderttausende Computer parallel arbeiten und wie einfach es ist.

Aber wahrscheinlich ist dies nur eine Nische der Art von Anwendungen, die diese Art von Einrichtung benötigen. Für viele, viele andere Anwendungen / Systeme funktionieren Prozedural und OO einwandfrei.

Es geht also darum, unseren Programmierhorizont zu erweitern und diese Konzepte wieder aufzunehmen, von denen wir einst dachten, sie würden nicht über die akademische Ebene hinausgehen.

Ich habe vor Jahren gelernt, in Lisp zu programmieren, und damals wusste ich nicht, dass das überhaupt FP ist. Inzwischen habe ich fast alles vergessen, aber ich kann Konzepte wie Rekursion sehr leicht verstehen.


2
Die Frage ist nach den Vorteilen von FP-ähnlichen Sprachen . Was Sie beschrieben haben, können Sie auch in traditionellen Sprachen tun.
Pacerier

6

Wir befinden uns in einer Ära, in der Multi-Core-Verarbeitung nicht nur in den Hinterzimmern von Wissenschaftslabors oder auf Spezialhardware durchgeführt wird. Es wird jetzt mit Commodity-Prozessoren gemacht. Die funktionale Programmierung, zumindest die meisten Varianten, denen ich ausgesetzt war, versucht im Allgemeinen, einen Blick auf nebenwirkungsfreie, zustandslose Recheneinheiten zu werfen. Dies ist das fundamentale Paradigma für Multicore-Arbeit, da es nicht erforderlich ist, den Zustand zwischen Prozessoren zu mischen.

Dies ist nur einer der Gründe, aber ein verdammt guter Grund dafür, dass die funktionale Programmierung greift.


5

Ich denke, die Hauptantwort auf diese Frage ist "Exposition".

Funktionale Programmierung ist nichts Neues, ich habe Haskell vor 12 Jahren an der Universität unterrichtet und es geliebt. Mußte aber selten die Sprache in meiner beruflichen Arbeit verwenden.

In letzter Zeit hat eine Reihe von Sprachen im Hauptstrom Fuß gefasst, die einen Multi-Paradigmen-Ansatz verwenden. F # , JavaScript als Paradebeispiel.

Insbesondere JavaScript wird aufgrund der Arbeit an dynamischen modernen Websites für viele Menschen zur Alltagssprache , insbesondere wenn es mit einer Framework-Sprache im funktionalen Stil wie jQuery oder Prototype verwendet wird. Diese Auseinandersetzung mit dem funktionalen Stil lässt die Menschen erkennen, welche Macht sie verleihen, insbesondere wenn man in der Lage ist, nach Belieben auf einen imperativen Stil zurückzugreifen.

Sobald die Leute entlarvt sind, probieren sie ausgereiftere Varianten von funktionalen Sprachen aus und beginnen, sie für alltägliche Aufgaben zu verwenden.

Da F # in Visual Studio 2010 zu einer erstklassigen Sprache wird und jQuery (et al.) Immer wichtiger wird, wird es immer realistischer, diese Sprachen zu verwenden, anstatt nur mit etwas Unklarem zu spielen oder isolierte Programme zu erstellen.

Denken Sie daran, dass Code wartbar sein muss - eine kritische Masse von Entwicklern muss Sprachen verwenden und unterstützen, damit sich Unternehmen bei der Verwendung sicher fühlen.


3

In diesem Vortrag erklärt Anders Hejlsberg seine Sicht auf das Thema.

[BEARBEITEN]

Entschuldigung, der Link war falsch. Jetzt zeigt es an die richtige Stelle.

Extrem kurze Zusammenfassung einiger Punkte des einstündigen Vortrags:

Funktionale Sprachen ermöglichen einen deklarativeren Programmierstil als prozedurale Sprachen. Daher konzentrieren sich in FLs geschriebene Programme in der Regel mehr auf das Was als auf das Wie . Aufgrund ihrer eleganten mathematischen Struktur lassen sich FLs auch von Compilern leichter optimieren und transformieren, was auch eine einfache Metaprogrammierung und den Aufbau eingebetteter DSLs ermöglicht. All dies zusammen macht Funktionsprogramme prägnanter und selbstdokumentierender als prozedurale Programme.

Außerdem müssen Programmiersprachen angesichts der vielen Kern-Ära der nahen Zukunft in der Lage sein, Multi-Threading / Verarbeitung auf verschiedene Arten zu nutzen. Multi-Threading auf Single-Core-Rechnern war in der Tat ein Time-Sharing-Mechanismus, und die Architektur der Systeme spiegelte dies wider. Multi-Threading auf Manycore-Maschinen wird sehr unterschiedlich sein. Funktionssprachen eignen sich besonders für die Parallelisierung, da sie Zustände meist vermeiden. Daher muss man sich nicht so viele Gedanken über die Integrität gemeinsam genutzter veränderlicher Daten machen (da in der Regel keine gemeinsam genutzten veränderlichen Daten vorhanden sind).


1
Können Sie das zusammenfassen?

1
@Thorbjorn Das erinnert mich an den Mann, der nicht zusammenfassen konnte . (Richten Sie das nicht auf Sie, antworten Sie dem Autor.)
Mark C

1
Der Link verweist nicht einmal auf die richtige Stelle.
Ken Bloom

2

Ich denke, es hängt mit der engen Korrelation zwischen dem funktionalen Programmierparadigma und der Programmierung für das Web zusammen.

Ruby on Rails brachte den gesamten Ansatz der funktionalen Programmierung auf den Punkt, da er einen sehr schnellen Weg zu einer funktionalen (heh heh) Webanwendung bot. Darüber gibt es eine interessante Diskussion über SO , und eine bestimmte Antwort ist bemerkenswert:

Funktionale Programmierung passt sehr gut zu Web-Apps. Die Web-App empfängt eine HTTP-Anfrage und erzeugt ein HTML-Ergebnis. Dies kann als Funktion von Anfragen an Seiten angesehen werden.

Vergleichen Sie dies mit Desktop-Apps, bei denen in der Regel ein langer Prozess, eine statusbehaftete Benutzeroberfläche und ein Datenfluss in mehrere Richtungen vorliegen. Dies ist eher für OO geeignet, die sich um Objekte mit Status- und Nachrichtenübergabe kümmern.

Angesichts der Tatsache, dass es funktionale Programmierung schon seit Ewigkeiten gibt, frage ich mich, warum ich nicht viele Stellenanzeigen sehe, die nach Lisp-Entwicklern für Greenfield-Webprojekte suchen.


Ich denke, funktionale Analogie gilt nur nebenbei für das Web, denn das zugrunde liegende Protokoll ist zustandslos. Webanwendungen sind nicht wirklich zustandslos, was in der Tat ein Grund ist, warum wir immer irgendwie mit HTTP umgehen müssen.
Mladen Jablanović

@Mladen Hmmm, ist es möglich, dass Sie den Client-Server-Kommunikationsstatus (HTTP) mit dem Anwendungsstatus (DAOs usw.) in Konflikt bringen? Zitiert Stefan Tilkov von hier ( codemonkeyism.com/stateless-applications-illusion ) "In einer Webanwendung sollte jede einzelne Anfrage genügend Informationen enthalten, um verarbeitet werden zu können, unabhängig davon, ob eine vorherige Anfrage aufgetreten ist oder nicht. Persistente serverseitige Ressource Der Status ist in Ordnung, der clientseitige Status ist in Ordnung, der Status für vorübergehende Kommunikation (Sitzung) nicht, weil er die Skalierbarkeit und Lesezeichenfähigkeit beeinträchtigt. " Dies ist die Basis von REST.
Gary Rowe

1
Vielleicht möchten Sie paulgraham.com/avg.html lesen , um besser zu verstehen, warum es nicht viele Stellenanzeigen gibt, die nach Lisp-Entwicklern suchen.

@ Thorbjørn Ravn Andersen Guter Artikel. Inspiriert mich, meinen Lisp-Editor herauszubrechen.
Gary Rowe

1

Die funktionale Programmierung gibt mir das gleiche prickelnde Gefühl von " Wow, das ist neu ", als ich vor Jahren anfing, mit Objekten zu experimentieren.

Mir ist klar, dass FP bei weitem kein neues Konzept ist, aber OO war es auch nicht, als es in den neunziger Jahren seinen wirklichen Durchbruch erlebte, als "jeder" plötzlich aus der prozeduralen Programmierung ausstieg. Dies war hauptsächlich auf den rechtzeitigen Erfolg von Java und später von C # zurückzuführen.

Ich stelle mir vor, dass mit FP irgendwann das Gleiche passieren wird, wenn sich die nächsten Sprachen auf die gleiche Weise verbreiten. So wie sie es zumindest in einigen Kreisen bereits mit Sprachen wie Scala und F # getan haben.


OO ist viel jünger als FP, aber es ist schon lange vorher ins Rampenlicht gerückt. Ich denke, die Klammer hat zu viele Menschen erschreckt
Javier

1

Hier sind meine Fragen: 1. Was hat zur jüngsten Begeisterung der FP beigetragen? Ist es nur Langeweile mit OO, oder hat sich etwas geändert, damit FP mehr gebraucht wird als zuvor? 2. Ist dies ein Hinweis auf eine FP-Zukunft? Oder ist dies eine Modeerscheinung, wie objektorientierte Datenbanken?

Andere haben gute technische Gründe angegeben.

Ich denke, der Hauptgrund, warum FP unter den durchschnittlichen Entwicklern und Managern an Bedeutung gewinnt, ist das Versprechen, eine bessere Nutzung von Multi-Core-CPUs zu ermöglichen. Von allem, was ich gelesen habe, ermöglicht FP eine einfachere (nicht einfache) parallele Programmierung.

Es wird in Zukunft weit verbreitet sein, wenn das Versprechen echt ist und erfüllt wird.


Das ist ein großes "Wenn". COBOL, "auf Englisch" zu sein, würde bedeuten, dass jeder programmieren konnte. AI würde die Programmierung überflüssig machen. OO würde das Programmieren so einfach machen wie das Zusammenbauen von Bastelspielzeugen. Codierer sind wie Rock-Groupies, die immer auf der Suche nach dem "nächsten großen Ding" und dem nächsten und dem nächsten ...
Mike Dunlavey

0

Ich denke, es ist eine Kombination aus zwei Trends:

  1. Funktionsmerkmale, die den gängigen Sprachen hinzugefügt werden (z. B. C #).
  2. Neue funktionale Sprachen werden erstellt.

Es gibt wahrscheinlich eine natürliche Grenze für den ersten Trend, aber ich gehe davon aus, dass jede neue Sprache die funktionale Programmierung unterstützen muss, zumindest als Option, um ernst genommen zu werden.


0

Früher haben Leute Programme geschrieben, die mit den nativen APIs des Betriebssystems auf dem Desktop ausgeführt werden, und diese APIs wurden (im Allgemeinen) in C geschrieben. Wenn Sie also ein Programm für die nativen APIs schreiben möchten, müssen Sie dies größtenteils tun schrieb das Programm in C.

Ich denke, dass die neue Innovation in den letzten 10 Jahren darin besteht, dass sich eine Vielzahl von APIs durchsetzt, insbesondere für Dinge wie die Webentwicklung, bei denen die Plattform-APIs irrelevant sind (da das Erstellen einer Webseite im Wesentlichen eine Manipulation von Zeichenfolgen beinhaltet). Da Sie nicht direkt mit der Win32-API oder der POSIX-API codieren, haben die Benutzer die Freiheit, funktionale Sprachen auszuprobieren.


0

Es ist ordentlich und geschickt und kitzelt dein Gehirn. Das ist gut.

Es ist auch, IMHO, ein klassischer Zug. Eine Lösung, die ein Problem sucht.

Es ist wie bei allen Start-up-Unternehmen, die von Ingenieuren gegründet wurden, die von einer Lieblingsidee geblendet wurden, die für eine Weile hell brennt, aber in aller Stille von Unternehmen überholt werden, die darauf gegründet sind, das zu liefern, was benötigt wird.

Das ist die neue Idee, die ich mir wünschen würde, bedarfsorientiertes Programmieren und nicht geschicktes, ideenbasiertes Programmieren. Vielleicht klingt das banal, aber ich denke, es kann tatsächlich ziemlich kreativ und geschickt sein.


-1

Auf jeden Fall wegen F #, obwohl manchmal schwer zu sagen ist, welche Ursache und welche Wirkung vorliegt.

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.