Was hat die Popularität von Lambda-Funktionen in modernen Mainstream-Programmiersprachen ausgelöst?

112

In den letzten Jahren haben sich anonyme Funktionen (AKA-Lambda-Funktionen) zu einem sehr beliebten Sprachkonstrukt entwickelt, und fast jede Haupt- / Mainstream-Programmiersprache hat sie eingeführt, oder es ist geplant, sie in einer bevorstehenden Überarbeitung des Standards einzuführen.

Anonyme Funktionen sind jedoch ein sehr altes und bekanntes Konzept in Mathematik und Informatik (erfunden von der Mathematikerin Alonzo Church um 1936 und verwendet von der Programmiersprache Lisp seit 1958, siehe z . B. hier ).

Warum haben die heutigen Standard-Programmiersprachen (von denen viele vor 15 bis 20 Jahren entstanden sind) Lambda-Funktionen von Anfang an nicht unterstützt und erst später eingeführt?

Und was hat in den letzten Jahren die massive Übernahme anonymer Funktionen ausgelöst? Gibt es ein bestimmtes Ereignis, eine neue Anforderung oder eine neue Programmiertechnik, die dieses Phänomen ausgelöst haben?

WICHTIGE NOTIZ

Der Schwerpunkt dieser Frage liegt auf der Einführung anonymer Funktionen in modernen Hauptsprachen (und daher mit wenigen Ausnahmen in nicht funktionalen Sprachen). Beachten Sie auch, dass anonyme Funktionen (Blöcke) in Smalltalk vorhanden sind, das keine funktionale Sprache ist, und dass normal benannte Funktionen auch in prozeduralen Sprachen wie C und Pascal seit langer Zeit vorhanden sind.

Bitte verallgemeinern Sie Ihre Antworten nicht, indem Sie von "der Übernahme des Funktionsparadigmas und seiner Vorteile" sprechen, da dies nicht das Thema der Frage ist.

Giorgio
quelle
7
Vor 15 bis 20 Jahren stellten die Leute die gleiche Frage nach OO ... es war kein neues Konzept, aber es hatte eine Explosion der Popularität.
MattDavey
7
@MattDavey Die meisten würden sicherlich nicht zustimmen, aber dann müsste ich sie daran erinnern, dass "die meisten Smalltalk-Entwickler" nicht wirklich so viele Leute sind; P
yannis
30
Ich denke, die interessantere Frage ist, was ihren Untergang ausgelöst hat ! Schließlich war es eine Zeit, als die meisten modernen Sprachen haben lambdas haben, dann Sprachen wie Java und C ++ populär wurde. (Obwohl ich Java nicht gerade als "moderne" Sprache bezeichnen würde. Das modernste Konzept in Java ist Generics, das bis in die späten 60er / frühen 70er Jahre zurückreicht. Sogar die Kombination der Funktionen, die Java bietet, Zeigersicherheit, Speichersicherheit, Typ Sicherheit, GC, statisch typisiert OO, Generika gab es alle in Eiffel im Jahr 1985 ... und viel besser, IMHO.)
Jörg W Mittag
31
Noch bevor Java 1.0 herauskam, wiesen so ziemlich alle darauf hin, dass Java Lambdas benötigt. Zu den Designern, die an Java gearbeitet haben, gehören Guy Steele (Lisp-Befürworter, Co-Designer von Scheme, Co-Autor von Common Lisp, Designer von Fortress), James Gosling (schrieb den ersten Emacs-Lisp-Interpreter für PCs) und Gilad Bracha (Smalltalk) Befürworter, Co-Designer von Animorphic Smalltalk, Designer von Newspeak), Phil Wadler (Co-Designer von Haskell), Martin Odersky (Designer von Scala). Wie Java ohne Lambdas gelandet ist, ist mir wirklich ein Rätsel.
Jörg W Mittag
8
"Ein kleines bisschen" bedeutet oft 50% Funktion, 50% Rauschen.
Kevin Cline

Antworten:

86

Es ist sicherlich ein Trend zur funktionalen Programmierung oder zumindest zu bestimmten Aspekten festzustellen. Einige der populären Sprachen, die irgendwann anonyme Funktionen angenommen haben, sind C ++ ( C ++ 11 ), PHP ( PHP 5.3.0 ), C # ( C # v2.0 ), Delphi (seit 2009), Objective C ( Blöcke ) und Java 8 bringt Unterstützung für Lambdas in die Sprache . Und es gibt populäre Sprachen, die im Allgemeinen nicht als funktionstüchtig gelten, aber von Anfang an oder zumindest früh anonyme Funktionen unterstützen, zum Beispiel JavaScript.

Wie bei allen Trends ist der Versuch, nach einem einzelnen Ereignis zu suchen, das sie auslöste, wahrscheinlich eine Zeitverschwendung. In der Regel handelt es sich dabei um eine Kombination von Faktoren, von denen die meisten nicht quantifizierbar sind. Practical Common Lisp , veröffentlicht im Jahr 2005, hat möglicherweise eine wichtige Rolle dabei gespielt, Lisp als praktische Sprache neu in den Fokus zu rücken , da Lisp lange Zeit hauptsächlich eine Sprache war, die Sie in einem akademischen Umfeld oder in sehr spezifischen Nischenmärkten kennengelernt haben. Die Popularität von JavaScript hat möglicherweise auch eine wichtige Rolle dabei gespielt, anonyme Funktionen neu in den Fokus zu rücken, wie munificent in seiner Antwort erklärt .

Abgesehen von der Übernahme funktionaler Konzepte aus Mehrzwecksprachen ist auch eine Verlagerung hin zu funktionalen (oder überwiegend funktionalen) Sprachen festzustellen. Sprachen wie Erlang (1986), Haskell (1990), OCaml (1996), Scala (2003), F # (2005), Clojure (2007) und sogar domänenspezifische Sprachen wie R (1993) scheinen eine starke Anhängerschaft zu haben nachdem sie eingeführt wurden. Der allgemeine Trend hat die Aufmerksamkeit auf ältere funktionale Sprachen wie Scheme (1975) und offensichtlich Common Lisp gelenkt.

Ich denke, das einzig wichtigere Ereignis ist die Übernahme der funktionalen Programmierung in der Branche. Ich habe absolut keine Ahnung, warum dies früher nicht der Fall war, aber es scheint mir, dass die funktionale Programmierung irgendwann in den frühen und mittleren 90er Jahren ihren Platz in der Branche gefunden hat, angefangen (vielleicht) mit Erlangs Verbreitung in Telekommunikation und Haskells Übernahme in der Luft- und Raumfahrt sowie im Hardware-Design .

Joel Spolsky hat einen sehr interessanten Blog-Beitrag geschrieben, The Perils of JavaSchools , in dem er sich gegen den (damaligen) Trend der Universitäten ausspricht , Java anderen, vielleicht schwieriger zu erlernenden Sprachen vorzuziehen . Der Blogbeitrag hat zwar wenig mit funktionaler Programmierung zu tun, identifiziert jedoch ein zentrales Problem:

Darin liegt die Debatte. Das jahrelange Schleudern von faulen CS-Studenten wie mir, kombiniert mit Beschwerden aus der Industrie darüber, wie wenig CS-Majors an amerikanischen Universitäten studieren, hat einen Tribut gefordert, und in den letzten zehn Jahren ist eine große Anzahl ansonsten perfekter Schulen zu 100% auf Java umgestiegen. Es ist hip, die Personalvermittler, die "grep" verwenden, um Lebensläufe zu bewerten, scheinen es zu mögen, und am allerbesten ist, dass Java nicht schwer genug ist, um die Programmierer wirklich auszumerzen, ohne den Teil des Gehirns, der Zeiger oder Rekursionen ausführt Die Abbrecherquoten sind niedriger und die Informatikabteilungen haben mehr Studenten und größere Budgets, und alles ist in Ordnung.

Ich erinnere mich noch, wie sehr ich Lisp hasste, als ich sie während meiner Studienzeit zum ersten Mal traf. Es ist definitiv eine harte Geliebte und es ist keine Sprache, in der man sofort produktiv sein kann (zumindest konnte ich das nicht). Im Vergleich zu Lisp ist Haskell (zum Beispiel) viel freundlicher, Sie können produktiv sein, ohne so viel Aufwand und ohne sich wie ein Vollidiot zu fühlen, und das könnte auch ein wichtiger Faktor bei der Umstellung auf funktionale Programmierung sein.

Alles in allem ist das eine gute Sache. Mehrere Mehrzwecksprachen verwenden Konzepte des Paradigmas, die den meisten ihrer Benutzer zuvor möglicherweise nicht zutreffend erschienen sind, und die Kluft zwischen den Hauptparadigmen verringert sich.

Verwandte Fragen:

Weitere Lektüre:

yannis
quelle
Danke für die Antwort (und viele interessante Ideen). +1 Dennoch würde ich argumentieren, dass die Einführung von (nur) Lambdas in eine Programmiersprache ein sehr kleiner Schritt in Richtung FP ist und für viele sogar verwirrend sein kann (was machen Lambdas in einer imperativen Sprache alleine?). Nach dem Erlernen von Haskell, Scala und SML habe ich nicht das Gefühl, dass ich echte FP mit einer imperativen Sprache machen kann, die nur Lambdas unterstützt (was ist mit Currying und Pattern Matching, Unveränderlichkeit?).
Giorgio
Lassen Sie uns diese Diskussion im Chat fortsetzen
Giorgio
2
@YannisRizos: Perls hatte anonyme Funktionen seit der ersten Veröffentlichung von 5 (1994), aber sie waren bis 5.004 (1997) nicht ganz "richtig".
Blrfl
1
@penartur Das dachte ich auch, aber ein freundlicher Redakteur korrigierte mich, indem er mich hierhin zeigte: msdn.microsoft.com/en-us/library/0yw3tz5k%28v=vs.80%29.aspx
yannis
Ich denke, dass das wichtigste "Ereignis", das die Popularität von funktionalen Sprachen hervorgebracht hat, das Web ist. Insbesondere die Verlagerung von Desktop-Programmen auf die Serverseite. Dies gibt dem Entwickler die Freiheit, eine Programmiersprache zu wählen. Paul Graham und Lisp in den 90er Jahren sind ein bemerkenswertes Beispiel.
Gilad Naor
32

Ich finde es interessant, wie sehr die Popularität der funktionalen Programmierung mit dem Wachstum und der Verbreitung von Javascript einherging. Javascript hat viele radikale Merkmale entlang des funktionalen Programmierspektrums, die zum Zeitpunkt seiner Erstellung (1995) unter den gängigen Programmiersprachen (C ++ / Java) nicht sehr beliebt waren. Es wurde plötzlich in den Mainstream als einzige clientseitige Web-Programmiersprache eingeführt. Plötzlich mussten viele Programmierer einfach Javascript beherrschen, und deshalb musste man etwas über funktionierende Programmiersprachen-Funktionen wissen.

Ich frage mich, wie beliebt funktionierende Sprachen / Features wären, wenn nicht der plötzliche Aufstieg von Javascript gewesen wäre.

Doug T.
quelle
5
Javascript ist sicherlich eine wichtige Sprache, aber ich bin mir nicht sicher, ob die Einführung von Javascript die Popularität der funktionalen Programmierung allein erklären kann: Viele andere funktionale Programmiersprachen sind in den letzten Jahren aufgetaucht, wie Yannis in seiner Antwort gezeigt hat .
Giorgio
8
@Giorgio - es gab vielleicht viele andere funktionale Programmiersprachen, aber (relativ) niemand benutzt sie. Die Verwendung von JS und die verstärkte Ansicht, dass die C ++ / Java-Art, Funktoren zu erstellen, schmerzhaft und ärgerlich ist, sind wirklich die treibenden Kräfte für den Mainstream, selbst wenn die akademischeren Sprachen die Art und Weise festlegten, wie sie implementiert werden sollten.
Telastyn
1
Die Popularität dynamischer Sprachen im Allgemeinen wird als eine Erklärung für die Popularität von Haskell angedeutet
yannis
Der Schwerpunkt der Frage liegt auch nicht auf der Popularität von FP im Allgemeinen, sondern auf der späten Einführung anonymer Funktionen in universellen, nicht funktionalen Sprachen. Auch wenn die große Öffentlichkeit (die meisten Programmierer) sie nicht kannte, kannten sie die Sprachdesigner sehr gut. Es muss einen Grund gegeben haben, sie am Anfang wegzulassen. Vielleicht galten sie für die Entwickler der frühen 90er Jahre als nicht intuitiv.
Giorgio
@giorgio - Die Implementierung ist weitaus schwieriger als bei Java-Funktoren. Kombinieren Sie das mit dem Mangel an Wissen / Akzeptanz und es ist eine ziemlich klare Designwahl.
Telastyn
27

Ereignis JavaScript und DOM - Handler dazu geführt, dass Millionen von Programmierern hatten zumindest ein wenig über First - Class - Funktionen zu tun , um zu lernen , jede auf der Web - Interaktivität.

Von dort ist es ein relativ kurzer Schritt zu anonymen Funktionen. Da JavaScript nicht geschlossen wird this, empfiehlt es Ihnen auch dringend, mehr über Schließungen zu erfahren. Und dann bist du goldrichtig: Du verstehst anonyme erstklassige Funktionen, die über lexikalische Bereiche hinausgehen.

Sobald Sie sich damit vertraut gemacht haben, möchten Sie es in jeder von Ihnen verwendeten Sprache.

herrlich
quelle
7
+1 Es geht nicht nur um anonyme Funktionen. Verschlüsse sind ein viel umfassenderes Konzept als nur die Definition einer temporären Funktion inline.
Phkahler
@phkahler: Sie haben Recht und in diesem Sinne hat Java bereits Closures (und ist noch leistungsfähiger als das, was Sie mit einem Funktionsliteral erhalten), aber es fehlt eine prägnante Notation für den allgemeinen Fall einer anonymen Ein-Methoden-Klasse.
Giorgio
17

Es ist sicherlich nicht der einzige Faktor, aber ich werde auf die Beliebtheit von Ruby hinweisen. Nicht zu sagen, dass dies wichtiger ist als eine der sechs Antworten, die bereits an der Tafel stehen, aber ich denke, dass viele Dinge gleichzeitig passiert sind und dass es nützlich ist, sie alle aufzuzählen.

Ruby ist keine funktionale Sprache, und ihre Lambdas, Prods und Blöcke scheinen klobig zu sein, wenn Sie so etwas wie ML verwenden. Fakt ist jedoch, dass sie den Begriff des Mappings und Reduzierens auf eine Generation junger Programmierer populär gemacht haben, die vor Java und PHP fliehen, um nach hipper zu suchen Weiden. Lambdas in mehreren Sprachen scheinen mehr als alles andere defensiv zu sein.

Aber die Block-Syntax und die Art und Weise, wie sie in .each, .map, .reduce usw. integriert ist, hat die Idee einer anonymen Funktion popluarisiert, auch wenn es sich tatsächlich um ein syntaktisches Konstrukt handelt, das sich wie eine Coroutine verhält. Und die einfache Konvertierung in einen Proc über & macht ihn zu einem Gateway-Medikament für die funktionale Programmierung.

Ich behaupte, dass Ruby on Rails-Programmierer, die JavaScript schreiben, bereits darauf eingestellt waren, Dinge in einem leichten funktionalen Stil zu tun. Zusammen mit dem Bloggen durch Programmierer verbreitete sich die Erfindung von Reddit, Hacker News und Stack Overflow etwa zur gleichen Zeit und die Ideen verbreiteten sich schneller über das Internet als zu Zeiten von Newsgroups.

TL; DR: Ruby, Rails, JavaScript, Blogging und Reddit / Hacker News / Stack Overflow haben funktionale Ideen auf den Massenmarkt gebracht, sodass jeder wollte, dass sie in vorhandenen Sprachen vorliegen, um weitere Fehler zu vermeiden.

Reg Braithwaite
quelle
2
+1 Für eine gute Antwort und (wenn ich könnte, weil ich nur eine Gegenstimme habe) +1 für den Hinweis, dass "Lambdas in mehreren Sprachen mehr als alles andere Verteidigungsbewegungen zu sein scheinen (" Bleib dran! Wir haben auch solche !!) ". Ich denke, das ist auch ein Faktor. Für einige Sprachen sind Lambdas eine nette Eigenschaft, die, obwohl sie der Sprache insgesamt sehr wenig Ausdruckskraft verleihen, der Sprache eine gewisse Popularität verleiht (a Zahl der Programmierer scheint zu glauben, dass die Unterstützung anonymer Funktionen der vollständigen Unterstützung der funktionalen Programmierung entspricht.)
Giorgio
2
Ich denke wirklich, dass dies der Grund ist, warum die meisten Sprachen in den letzten Jahren Block-Syntax implementiert haben. Die einzige Möglichkeit, dies sicherzustellen, besteht darin, die Sprachentwickler nach ihren Motiven zu fragen. Wir können nur imo spekulieren.
SpoBo
Ruby ist für mich die Sprache, die Block- Rock und sehr ansprechend gemacht hat, also +1. Haskell könnte auch eine Wirkung gehabt haben.
Rogerdpack
13

Wie Yannis betonte, gibt es eine Reihe von Faktoren, die die Übernahme von Funktionen höherer Ordnung in Sprachen beeinflusst haben, die zuvor ohne waren. Einer der wichtigsten Punkte, auf die er nur kurz eingegangen ist, ist die Verbreitung von Multi-Core-Prozessoren und damit der Wunsch nach einer paralleleren und gleichzeitigeren Verarbeitung.

Der Map / Filter / Reduce-Stil der funktionalen Programmierung ist sehr parallelisierbar, sodass der Programmierer problemlos mehrere Kerne verwenden kann, ohne expliziten Threading-Code schreiben zu müssen.

Wie Giorgio bemerkt, geht es bei der funktionalen Programmierung nicht nur um Funktionen höherer Ordnung. Funktionen sowie ein Map / Filter / Reduce-Programmiermuster und Unveränderlichkeit bilden den Kern der funktionalen Programmierung. Zusammen ergeben diese Dinge leistungsstarke Werkzeuge für die parallele und gleichzeitige Programmierung. Zum Glück unterstützen viele Sprachen bereits den Begriff der Unveränderlichkeit, und selbst wenn dies nicht der Fall ist, können Programmierer die Dinge als unveränderlich behandeln, sodass Bibliotheken und Compiler asynchrone oder parallele Operationen erstellen und verwalten können.

Das Hinzufügen von Funktionen höherer Ordnung zu einer Sprache ist ein wichtiger Schritt, um die gleichzeitige Programmierung zu vereinfachen.

Aktualisieren

Ich werde ein paar detailliertere Beispiele hinzufügen, um auf die Bedenken von Loki einzugehen.

Betrachten Sie den folgenden C # -Code, der eine Sammlung von Widgets durchläuft und eine neue Liste von Widgetpreisen erstellt.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

Für eine große Sammlung von Widgets oder eine rechenintensive CalculateWidgetPrice (Widget) -Methode würde diese Schleife verfügbare Kerne nicht sinnvoll nutzen. Um die Preisberechnungen für verschiedene Kerne durchführen zu können, muss der Programmierer Threads explizit erstellen und verwalten, die Arbeit weitergeben und die Ergebnisse zusammenfassen.

Betrachten Sie eine Lösung, sobald Funktionen höherer Ordnung zu C # hinzugefügt wurden:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

Die foreach-Schleife wurde in die Select-Methode verschoben, wobei ihre Implementierungsdetails ausgeblendet wurden. Der Programmierer muss nur noch mitteilen, welche Funktion auf die einzelnen Elemente angewendet werden soll. Dies würde es der Select-Implementierung ermöglichen, die Berechnungen parallel auszuführen und alle Synchronisations- und Thread-Management-Probleme ohne Beteiligung des Programmierers zu lösen.

Aber Select funktioniert natürlich nicht parallel. Hier kommt Unveränderlichkeit ins Spiel. Die Implementierung von Select weiß nicht, dass die bereitgestellte Funktion (CalculateWidgets oben) keine Nebenwirkungen hat. Die Funktion kann den Status des Programms außerhalb der Ansicht von Select und seiner Synchronisierung ändern und alles beschädigen. In diesem Fall könnte beispielsweise der Wert von salesTax irrtümlich geändert werden. Reine funktionale Sprachen bieten Unveränderlichkeit, sodass die Select (Map) -Funktion sicher weiß, dass sich kein Zustand ändert.

C # behebt dies, indem es PLINQ als Alternative zu Linq bereitstellt. Das würde so aussehen:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Damit können Sie alle Kerne Ihres Systems voll ausnutzen, ohne diese Kerne explizit verwalten zu müssen.

Ben
quelle
Ich verweise auf den Wunsch nach einer paralleleren und gleichzeitigeren Verarbeitung. Er wird im ACM-Artikel "Eine Geschichte von Erlang" behandelt, auf den ich im vierten Absatz verweise. Aber es ist ein sehr guter Punkt, und ich hätte es wahrscheinlich ein bisschen weiter ausbauen sollen. +1, weil ich jetzt nicht muss; P
yannis
Du hast recht, ich habe nicht genau genug nachgesehen. Ich habe meine Bemerkung bearbeitet.
Ben
Oh, du
musstest
4
Nichts von dem, was Sie oben beschreiben, erfordert Lambdas. Die gleiche Funktionalität wird ebenso leicht mit benannten Funktionen erreicht. Hier dokumentieren Sie einfach ein causeund ein, perceived affectohne das zu erklären correlation. Die letzte Zeile IMO ist, worum es in der Frage geht; aber du hast nicht geantwortet. Warum vereinfacht es die gleichzeitige Programmierung?
Martin York
@Ben: Achten Sie darauf, dass Ihr Beispiel Funktionen höherer Ordnung betrifft, für deren Verwendung keine anonymen Funktionen erforderlich sind. Ihre Antwort enthält interessante Ideen (für eine andere Frage), ist aber momentan nicht aktuell.
Giorgio
9

Ich stimme vielen der Antworten hier zu, aber was interessant ist, ist, dass ich, als ich etwas über Lambdas lernte und mich auf sie stürzte, aus keinem der Gründe, die andere angesprochen haben, darauf gestoßen bin.

In vielen Fällen verbessern Lambda-Funktionen einfach die Lesbarkeit Ihres Codes. Bevor Sie eine Methode aufrufen, die einen Funktionszeiger (oder eine Funktion oder einen Delegaten) akzeptiert, mussten Sie den Hauptteil dieser Funktion an einer anderen Stelle definieren. Wenn Sie also "foreach" -Konstrukte hatten, musste Ihr Leser zu einem anderen springen Teil des Codes, um zu sehen, was genau Sie mit den einzelnen Elementen vorhatten.

Wenn der Hauptteil der Funktion, die Elemente verarbeitet, nur aus wenigen Zeilen besteht, würde ich eine anonyme Funktion verwenden, da jetzt beim Lesen von Code die Funktionalität unverändert bleibt, der Leser jedoch nicht hin und her springen muss, sondern die gesamte Implementierung genau dort vor ihm.

Viele der funktionalen Programmiertechniken und Parallelisierungen könnten ohne anonyme Funktionen erreicht werden. deklarieren Sie einfach einen regulären und geben Sie einen Verweis darauf weiter, wann immer Sie müssen. Aber mit Lambdas wird das Schreiben von Code und das Lesen von Code erheblich vereinfacht.

DXM
quelle
1
Sehr gute Erklärung (+1). Lisp-Programmierer sind sich all dessen seit 1958 bewusst. ;-)
Giorgio
4
@ Giorgio: Sicher, aber Lispel-Programmierer mussten auch spezielle Tastaturen mit verstärkten Tasten zum Öffnen / Schließen in Klammern kaufen :)
DXM
@ DXM: keine Keyboards, sie bekommen ein zusätzliches Eingabegerät, das wie ein Piano-Pedal zum Öffnen und Schließen von Klammern
aussieht ;-)
@DXM, vartec: Ich habe in letzter Zeit einige Scheme gemacht und finde die Klammern in Ordnung. Einige C ++ - Codes können viel kryptischer sein (und ich habe viel mehr Erfahrung mit C ++ als mit Scheme). :-)
Giorgio
9

Ich glaube, dass ein Faktor, der in die jüngste Geschichte einbezogen wurde, die Hinzufügung von Generika zu Java und .NET war. Das führt natürlich zu Func < , > und anderen stark typisierten Rechenabstraktionen (Task < >, Async < > etc.)

In der .NET-Welt haben wir diese Funktionen genau hinzugefügt, um FP zu unterstützen. Dies löste eine Reihe von kaskadierenden Sprachaufgaben im Zusammenhang mit der funktionalen Programmierung aus, insbesondere C # 3.0, LINQ, Rx und F #. Diese Entwicklung hat auch andere Ökosysteme beeinflusst und setzt sich bis heute in C #, F # und TypeScript fort.

Natürlich hilft es auch, wenn Haskell bei MSR arbeitet :)

Natürlich gab es auch viele andere Einflüsse (JS sicherlich) und diese Schritte wurden wiederum von vielen anderen Dingen beeinflusst - aber das Hinzufügen von Generika zu diesen Sprachen half, die starre OO-Orthodoxie der späten 90er Jahre in weiten Teilen der Software-Welt zu durchbrechen und zu öffnen die Tür für FP.

Don Syme

ps F # war 2003, nicht 2005 - obwohl wir sagen würden, dass es erst 2005 1.0 erreichte. Wir haben 2001-02 auch einen Haskell.NET-Prototyp erstellt.

Don Syme
quelle
Herzlich willkommen! Ich habe 2005 für F # verwendet, da dies das Jahr ist, das im Wikipedia-Artikel von F # als das Jahr der ersten stabilen Veröffentlichung angegeben wurde. Möchten Sie, dass ich es auf 2003 ändere?
Yannis
4

Nach allem, was ich sehe, konzentrieren sich die meisten Antworten darauf, zu erklären, warum die funktionale Programmierung im Allgemeinen ihr Comeback und ihren Weg in den Mainstream gefunden hat. Ich hatte das Gefühl, dass dies jedoch nicht wirklich die Frage nach anonymen Funktionen beantwortet und warum sie plötzlich so populär wurden.

Was wirklich an Popularität gewonnen hat, sind Verschlüsse . Da in den meisten Fällen Abschlüsse übergebene Wegwerffunktionen sind, ist es offensichtlich sinnvoll, für diese anonyme Funktionssyntax zu verwenden. In einigen Sprachen ist dies die einzige Möglichkeit, einen Abschluss zu erzielen.

Warum haben Verschlüsse an Popularität gewonnen? Weil sie bei der ereignisgesteuerten Programmierung beim Erstellen von Rückruffunktionen nützlich sind . Es ist derzeit die Art, JavaScript-Client-Code zu schreiben (tatsächlich ist es die Art, GUI-Code zu schreiben). Es ist derzeit auch die Art und Weise, hocheffizienten Back-End-Code sowie Systemcode zu schreiben, da in ereignisgesteuerten Paradigmen geschriebener Code normalerweise asynchron und nicht blockierend ist . Für das Back-End wurde dies als Lösung für das C10K-Problem populär .

vartec
quelle
Vielen Dank, dass Sie betont haben, dass es bei dieser Frage nicht um funktionale Programmierung (+1) geht, da (1) die Idee eines Codeblocks, der als Argument weitergegeben wird, auch in nicht funktionalen Sprachen wie Smalltalk und (2) Mutating State verwendet wird Aus dem lexikalischen Kontext eines Closures (wie in vielen Lambda-Implementierungen möglich) erfasst, ist definitiv nicht funktionsfähig . Und ja, bei Schließungen ist der Schritt zu anonymen Schließungen kurz. Das Interessante ist, dass auch Verschlüsse seit langem bekannt sind und seit den achtziger Jahren (soweit ich weiß) ereignisgesteuertes Programmieren eingesetzt wird.
Giorgio
Aber vielleicht hat sich erst in den letzten Jahren herausgestellt, dass Verschlüsse viel häufiger verwendet werden können als bisher angenommen.
Giorgio
@Giorgio: Ja, die meisten Konzepte, die derzeit verwendet werden, gibt es schon sehr, sehr lange. Sie wurden jedoch nicht so verwendet, wie sie jetzt verwendet werden.
Vartec
1

Ich denke, der Grund dafür ist die zunehmende Verbreitung von gleichzeitiger und verteilter Programmierung, bei der der Kern der objektorientierten Programmierung (das Einkapseln des sich ändernden Zustands in Objekte) nicht mehr gilt. Im Falle eines verteilten Systems, denn es ist keine gemeinsamen Zustand (und Software - Abstraktionen dieses Konzepts sind undicht) und im Falle einer gleichzeitigen System, da richtig synchronisieren Zugriff auf gemeinsam genutzten Zustand ist umständlich und fehleranfällig erwiesen. Das heißt, einer der Hauptvorteile der objektorientierten Programmierung gilt nicht mehr für viele Programme, wodurch das objektorientierte Paradigma weitaus weniger hilfreich ist als früher.

Im Gegensatz dazu verwendet das Funktionsparadigma keinen veränderlichen Zustand. Alle Erfahrungen, die wir mit Funktionsparadigmen und -mustern gesammelt haben, sind daher sofort auf gleichzeitige und verteilte Berechnungen übertragbar. Und anstatt das Rad neu zu erfinden, leiht sich die Branche diese Muster und Sprachmerkmale, um ihren Bedürfnissen gerecht zu werden.

Meriton
quelle
4
Anonyme Funktionen in einigen Mainstream-Sprachen (z. B. C ++ 11) ermöglichen einen veränderlichen Status (sie können sogar Variablen aus der definierenden Umgebung erfassen und sie während ihrer Ausführung ändern). Ich denke also, dass das Sprechen über das Funktionsparadigma im Allgemeinen und über die Unveränderlichkeit im Besonderen etwas außerhalb des Rahmens der gestellten Frage liegt.
Giorgio
Nachdem Sie gerade einige der Funktionshinweise für Java 8 gelesen haben, besteht eines der Hauptziele des Projekts Lambda darin, die Parallelität zu unterstützen. Und DAS bringt uns sofort zu der Mutabilitäts-Clusterbombe, in die all diese wunderbaren Javabohnen geraten werden. Sobald Java Lambdas erhält (vorausgesetzt, dass dies in der endgültigen Version 8 tatsächlich der Fall ist), müssen sie das standardmäßig unveränderliche Problem auf irgendeine Weise beheben (es zerstört die Sprache und denkt stattdessen in Lisp - Nebeneffekt-freien Funktionen - von in COBOL - Schlag auf DATA DIVISION / COPYBOOK)
Roboprog
Gut gesagt. Die Abkehr vom veränderlichen Status erleichtert die Parallelität und Technologien wie cascalog und spark verteilen die funktionale Programmierung problemlos auf mehrere Computer. Unter glennengstrand.info/analytics/distributed/functional/… finden Sie weitere Informationen dazu, wie und warum.
Glenn
1

Wenn ich meine 0,02 € hinzufügen darf, obwohl ich der Wichtigkeit der Einführung des Konzepts durch JavaScript zustimmen würde, würde ich meiner Meinung nach mehr als die gleichzeitige Programmierung der aktuellen Mode der asynchronen Programmierung die Schuld geben. Bei asynchronen Aufrufen (die für die Webseiten erforderlich sind) sind einfache anonyme Funktionen offensichtlich so nützlich, dass sich jeder Webprogrammierer (dh jeder Programmierer) mit dem Konzept vertraut machen musste.

mcepl
quelle
1

Ein anderes wirklich altes Beispiel für etwas, das anonymen Funktionen / Lambdas ähnelt, ist Call-by-Name in Algol 60. Beachten Sie jedoch, dass Call-by-Name der Übergabe von Makros als Parameter näher kommt als der Übergabe von True-Funktionen, und es ist fragiler / schwieriger als Ergebnis verstehen.

Stephen C
quelle
0

Hier die Abstammung nach bestem Wissen.

  • 2005: Javascript hat zuletzt die Programmierung höherer Ordnung mit Lambdas zurück in den Mainstream gebracht. Insbesondere Bibliotheken wie underscore.js und jquery . Eine der ersten dieser Bibliotheken war prototype.js , die jquery um etwa ein Jahr älter ist als jquery. Prototype basiert auf dem Enumerable-Modul von Ruby, das uns zu ...
  • 1996: Rubys Enumerable-Modul wurde ganz offensichtlich von Smalltalks Sammlungs-Framework inspiriert. Wie Matz in vielen Interviews erwähnt hat, führt uns das zu…
  • 1980: Smalltalk verwendet viel Programmierung höherer Ordnung und stellt eine Auflistungs-API bereit, die stark von der Programmierung höherer Ordnung Gebrauch macht (z. B. die Iterable-Klasse von GNU Smalltalk ). Im idiomatischen Smalltalk-Code finden Sie keine for-Schleifen, sondern nur Aufzählungen höherer Ordnung. Leider wurden bei Java, als Smalltalks Collection Framework 1998 nach Java portiert wurde, die übergeordneten Aufzählungen weggelassen. Auf diese Weise wurde das Programmieren höherer Ordnung in den nächsten zehn Jahren aus dem Mainstream verdrängt! Smalltalk hat viele Vorfahren, aber relevant für die Frage von OP ist LISP, was uns zu ... führt.
  • 1958: LISP hat offensichtlich eine Programmierung höherer Ordnung im Kern.
akuhn
quelle
Amiss ist natürlich die ganze ML-Abstammung. ML, SML, OCaml, Haskell, F #. Das muss etwas
ausmachen
-1

Anonyme Funktionen sind nett, weil es schwierig ist, Dinge zu benennen, und wenn Sie eine Funktion nur einmal verwenden, braucht sie keinen Namen.

Lambda-Funktionen haben sich erst in jüngster Zeit zum Mainstream entwickelt, da bis vor kurzem die meisten Sprachen Closures nicht unterstützten.

Ich würde vorschlagen, dass Javascript diesen Mainstream vorangetrieben hat. Es ist eine universelle Sprache, die keine Möglichkeit bietet, Parallelität auszudrücken, und anonyme Funktionen erleichtern die Verwendung von Rückrufmodellen. Zusätzlich haben populäre Sprachen wie Ruby und Haskell beigetragen.

Matt Joiner
quelle
1
"Lambda-Funktionen sind erst in letzter Zeit zum Mainstream geworden, weil bis vor kurzem die meisten Sprachen Closures nicht unterstützten." Man könnte sofort fragen: "Was hat die Popularität von Schließungen in modernen Programmiersprachen ausgelöst?"
Giorgio
Ich weiß, dass Python nicht die beste Implementierung von Lambdas bietet. Aber in Bezug auf die Popularität hat es wahrscheinlich mehr beigetragen als Haskell.
Muhammad Alkarouri