In letzter Zeit ist mir aufgefallen, dass funktionale Programmiersprachen immer beliebter werden . Ich habe kürzlich gesehen, dass der Tiobe-Index im Vergleich zum letzten Jahr immer beliebter geworden ist, obwohl die meisten von ihnen nach diesem Index nicht einmal die 50 beliebtesten Sprachen erreichen.
Und das ist schon lange so. Funktionale Programmierung ist einfach nicht so populär geworden wie andere Modelle (dh objektorientierte Programmierung).
Ich habe jedoch ein wiedergeborenes Interesse an der Leistungsfähigkeit der funktionalen Programmierung gesehen, und jetzt, da Multicores immer beliebter werden, zeigen Entwickler Interesse an anderen Modellen der Parallelität, die bereits in der Vergangenheit von Sprachen wie Haskell und Erlang untersucht wurden.
Ich sehe mit großem Interesse, dass trotz der mangelnden Akzeptanz in der Gemeinschaft immer mehr Sprachen dieser Art auftauchen. Clojure (2007), Scala (2003), F # (2002) sind nur drei Beispiele des letzten Jahrzehnts.
Ich selbst habe einige Zeit investiert, um Haskell und Scala zu lernen. Und ich finde großes Potenzial in dem Paradigma, das für mich neu war, obwohl ich so lange da draußen war.
Und natürlich ist meine größte Frage, ob einige von ihnen populär genug werden, um sich überhaupt darum zu bemühen, aber diese Frage könnte nicht einmal Mandrake beantworten, trotz all der Aufregung, die die Leute über sie machen.
Was ich fragen möchte ist:
- In welchen Szenarien sollte ich eine funktionierende Programmiersprache als besser geeignet für eine bestimmte Aufgabe betrachten? Neben dem in letzter Zeit beliebten Multicore-Problem der Parallelprogrammierung.
- Wenn ich mich für eine funktionierende Programmiersprache entscheiden würde, welche wären für Sie die größten Tücken, denen ich begegnen würde? (Neben dem Paradigmenwechsel und der Schwierigkeit, die Leistung aufgrund fauler Bewertung zu bewerten).
- Wie würden Sie bei so vielen funktionalen Programmiersprachen die auswählen, die Ihren Anforderungen am besten entspricht?
Empfehlungen für die weitere Forschung werden mehr als willkommen sein.
Ich habe im Internet nach Meinungen gesucht, und es scheint, dass all diese erneute Beliebtheit auf die Idee zurückzuführen ist, dass wir jetzt die Mauer von Moores Gesetz sprengen und funktionierende Programmiersprachen kommen und uns heldenhaft retten werden. Aber wenn dies der Fall ist, würde ich sagen, dass es mehr Wahrscheinlichkeiten für die Anpassung bestehender populärer Sprachen an das Paradigma gibt.
Einige von Ihnen, die jeden Tag mehr Erfahrung mit diesen Sprachen haben, können mehr Einblicke in das Thema gewähren. Alle Ihre Meinungen werden besser gewürdigt und sorgfältig abgewogen.
Danke im Voraus!
Antworten:
Alles, was das Erstellen einer Sequenz abgeleiteter Datenelemente mit einer Reihe von Transformationsschritten umfasst.
Im Wesentlichen das "Tabellenkalkulationsproblem". Sie haben einige Anfangsdaten und eine Reihe von zeilenweisen Berechnungen, die Sie auf diese Daten anwenden können.
Unsere Produktionsanwendungen enthalten eine Reihe statistischer Zusammenfassungen von Daten. dies wird am besten funktional angegangen.
Wir führen häufig drei monströse Datensätze zusammen. Ähnlich wie ein SQL-Join, jedoch nicht so verallgemeinert. Daran schließt sich eine Reihe von Berechnungen abgeleiteter Daten an. Dies ist alles nur funktionale Transformationen.
Die Anwendung ist in Python geschrieben, wird jedoch in einem funktionalen Stil unter Verwendung von Generatorfunktionen und unveränderlichen benannten Tupeln geschrieben. Es ist eine Komposition von Funktionen auf niedrigerer Ebene.
Hier ist ein konkretes Beispiel für eine funktionale Zusammensetzung.
Auf diese Weise beeinflusst die funktionale Programmierung Sprachen wie Python.
Manchmal wird so etwas geschrieben:
Unveränderliche Gegenstände sind die härteste Hürde.
Oft werden Sie Werte berechnen, die neue Objekte erstellen, anstatt vorhandene Objekte zu aktualisieren. Die Vorstellung, dass es sich um ein veränderliches Attribut eines Objekts handelt, ist eine schwierige mentale Angewohnheit, sich davon zu lösen.
Eine abgeleitete Eigenschaft oder Methodenfunktion ist ein besserer Ansatz. Stateful Objekte sind eine schwierige Angewohnheit zu brechen.
Es ist zunächst egal. Wähle eine Sprache zum Lernen. Sobald Sie etwas wissen, sind Sie in der Lage, ein anderes auszuwählen, das Ihren Bedürfnissen besser entspricht.
Ich habe Haskell gelesen, um zu verstehen, was Python fehlt.
quelle
"Funktional" ist eine Reihe verschiedener Funktionen, von denen jede für sich nützlich ist. Ich finde es sinnvoller, sie einzeln zu betrachten.
Unveränderlichkeit
Jetzt, da ich damit vertraut bin, versuche ich immer, ein unveränderliches Ergebnis zu erzielen, auch in einem objektorientierten Programm. Es ist einfacher, über das Programm nachzudenken, wenn Sie Daten vom Typ Wert haben. Normalerweise benötigen Sie Anpassungsfähigkeit für Dinge wie GUIs und Leistungsengpässe. Meine Entitäten (mit NHibernate) sind auch veränderbar (was sinnvoll ist, weil sie Daten modellieren, die in einer Datenbank gespeichert sind).
Funktioniert als erstklassige Typen
Wie auch immer Sie es nennen möchten: Das Weitergeben von Delegierten, Aktionen oder Funktionen ist ein sehr praktischer Weg, um eine ganze Klasse von Problemen der realen Welt zu lösen, wie z. B. das "Loch im mittleren Muster". Ich habe auch festgestellt, dass das Übergeben eines Delegaten, einer Aktion oder einer Funktion an ein Objekt sauberer ist, als wenn diese Klasse ein Ereignis deklariert und dieses Ereignis verknüpft (vorausgesetzt, es gibt normalerweise nur einen "Listener"). Wenn Sie wissen, dass es einen Listener gibt, kann die Rückrufaktion als Konstruktorparameter übergeben werden (und in einem unveränderlichen Member gespeichert werden!)
In der Lage zu sein, Funktionen zu komponieren (zum Beispiel
Action<T>
nur eine zu werden,Action
ist in manchen Szenarien auch sehr nützlich.Wir sollten hier auch die Lambda-Syntax beachten, da Sie die Lambda-Syntax nur erhalten, wenn Sie Funktionen zu erstklassigen Typen hochstufen. Lambda-Syntax kann sehr ausdrucksstark und prägnant sein.
Monaden
Zugegeben, dies ist meine Schwachstelle, aber ich verstehe, dass Computerworkflows in F #, wie z. B. der
async
Workflow, eine Monade sind. Dies ist ein subtiles, aber sehr mächtiges Konstrukt. Es ist so leistungsfähig wie dasyield
Schlüsselwort, mit demIEnumerable
Klassen in C # erstellt werden. Im Grunde baut es eine Zustandsmaschine für Sie unter der Decke, aber Ihre Logik sieht linear aus.Lazy Evaluation & Rekursion
Ich habe diese zusammengestellt, weil sie zwar immer als Merkmale der funktionalen Programmierung zusammengefasst sind, aber so schnell in ansonsten unerlässliche Sprachen übergegangen sind, dass es schwierig ist, sie als funktional zu bezeichnen.
S-Ausdrücke
Ich bin mir nicht sicher, wo ich das ablegen soll, aber die Möglichkeit, den nicht kompilierten Code als Objekt zu behandeln (und ihn zu untersuchen / zu ändern), wie z. B. Lisp S-Expressions oder LINQ Expressions, ist in gewisser Weise das mächtigste Werkzeug der funktionalen Programmierung. Die meisten neuen "fließenden" .NET-Schnittstellen und DSLs verwenden eine Kombination aus Lambda-Syntax und LINQ-Ausdrücken, um einige sehr übersichtliche APIs zu erstellen. Ganz zu schweigen von Linq2Sql / Linq2Nhibernate, wo Ihr C # -Code "magisch" als SQL anstelle von C # -Code ausgeführt wird.
Das war die lange Antwort auf den ersten Teil Ihrer Frage ... jetzt ...
Die größte Gefahr für mich bestand darin, die Grenze zwischen funktionalen und imperativen Lösungen zu finden. Nachdem Sie jedoch beide Ansätze ein paar Mal ausprobiert haben, erhalten Sie ein Gefühl, das besser funktioniert.
Wenn Sie mit .NET vertraut sind, empfehle ich dringend F #. Wenn Sie jedoch mit der JVM vertraut sind, gibt es immer Clojure . Wenn Sie mehr akademisch als praktisch sind, würde ich mich für Common Lisp oder Scheme entscheiden. Wenn Sie Python bereits kennen, gibt es meines Erachtens bereits viele funktionale Konstrukte.
quelle
Dies trifft zu, wenn Sie Programme zählen, die von professionellen Programmierern entwickelt wurden (oder zumindest von Personen, die sich selbst als solche sehen). Wenn Sie Ihr Netz um Programme erweitern, die von Leuten entwickelt wurden, die sich selbst nicht als solche betrachten, kommt FP (oder zumindest das Programmieren in einem funktionalen Stil) OO ziemlich nahe (Excel, Mathematica, Matlab, R ... sogar "modernes" JavaScript) ).
Meine persönliche Meinung ist, dass Multicore nicht das Killer-Feature von FP ist (zumindest bis Haskell, Scala, Clojure, F # -Compiler das Problem mit der Cache-Lokalität lösen). Das Killer - Feature ist
map
,filter
,fold
und Freunde , die einem prägnanten Ausdruck einer großen Gruppe von Algorithmen ermöglichen. Hinzu kommen FP-Sprachen mit einer präziseren Syntax als die meisten gängigen OO-Sprachen.Da FP näher am relationalen Modell ist, verringert sich auch die Impedanzfehlanpassung mit RDBMS ... was - zumindest für Nicht-Programmierer - sehr schön ist.
Auch wenn es besonders schwierig ist, die Anforderungen an die Korrektheit zu erfüllen - in einer Form, die schwer zu testen ist (üblich beim wissenschaftlichen Rechnen / bei der Analyse großer Datenmengen, bei denen das Ziel darin besteht, zuvor unbekannte und als solche nicht spezifizierbare Ergebnisse zu erzielen), die FP bieten kann vorteile.
Wie viele Ihrer Probleme können gelöst werden, indem bereits vorhandene Bibliotheken / Frameworks auf welcher Plattform (z. B. JVM oder .Net) beendet werden? Wie viele sind brandneu? Gibt es Sprachkonstrukte, die diese Probleme direkt ausdrücken können?
Wie viel Kontrolle auf niedriger Ebene benötigen Sie für die räumliche und zeitliche Leistung Ihrer Anwendung?
Wie streng sind Ihre "Korrektheits" -Anforderungen?
Können Sie es sich leisten, Entwickler neu auszubilden und / oder mit den Vorteilen zu konkurrieren, die einige hochprofitable Nischen in der SW-Entwicklung bieten?
quelle
Angenommen, Sie sind ein C ++ / C # / Java-Entwickler in der Industrie ...
Seien Sie bereit für mürrische Kollegen, die nichts lernen wollen. Seien Sie auf spitze Chefs vorbereitet, die schlechte Sprachwahlen auferlegen, "weil sie einmal Kodierer waren". Seien Sie auf markige Akademiker in Foren vorbereitet, die Sie über Monoide bevormunden. Bereite dich auf endlose Sprachkriege vor, denn Scala hat nicht einmal die Möglichkeit, Anrufe zu eliminieren, und Clojure benötigt wirklich Fußpedale für alle Klammern und bringt mich nicht dazu, Erlang zu lernen.
Wenn Sie ein Web-Programmierer sind, sind wahrscheinlich Ihre Haare die größte Gefahr.
Ich würde mit Plattform beginnen:
quelle
Eine (zugegebenermaßen voreingenommene) Perspektive zu dieser Frage bietet der Blog von Bob Harper, Existential Type . Carnegie Mellon hat kürzlich sein CS-Curriculum überarbeitet, um zunächst funktionales Programmieren zu unterrichten. Andere Paradigmen werden erst unterrichtet, wenn eine solide Grundlage für funktionales Programmieren geschaffen wurde, und Harper gibt einen Schlag für Schlag, während das neue Curriculum in der Praxis eingeführt wird .
Harper ist einer der Hauptentwickler der Standard-ML-Programmiersprache. Man kann also sagen, dass seine eigene Meinung zu diesem Thema im Voraus erraten werden kann, und er scheut sich sicherlich nicht, umstrittene Aussagen zu machen, wenn er für diese Position argumentiert, aber er macht sein Fall gut.
quelle
var
einziges Mal eine veränderbare Sammlung verwendet. Imperatives Denken ist also IMO eine Art vorzeitige Optimierung, die, wie wir alle wissen, die Wurzel allen Übels ist.Es gibt keine Zauberformel, die Ihnen sagt, wann Sie die funktionale Programmierung verwenden sollen. Es ist nicht so, dass die objektorientierte Programmierung besser zu unseren aktuellen Programmiersituationen passt. Es ist nur eine andere Art, Programme in Bezug auf eine andere Menge von Abstraktionen zu strukturieren.
Funktionale Programmierung hat nichts mit Faulheit zu tun. ML und OCaml sind funktionale und strenge Sprachen. Die größte Hürde, der Sie gegenüberstehen, besteht darin, Dinge in unveränderlichen Werten zu strukturieren und sich mit der Abstraktion zu befassen, die im Typensystem für Nebenwirkungen verwendet wird. Funktionale Sprachen eignen sich besser zur Optimierung, da sie Nebenwirkungen im Typensystem sehr deutlich machen. Haskell verwendet Monaden, aber es gibt andere Ansätze für die Verwendung von Effekten in reinen funktionalen Sprachen. Clean hat Einzigartigkeitstypen und einige andere Sprachen in der Entwicklung haben andere Dinge.
Unter den mir bekannten Programmiersprachen kann man nur Haskell und Clean als funktionale Sprachen bezeichnen. Alle anderen erlauben Nebenwirkungen, ohne diese im Typensystem explizit zu machen. Wenn Sie also Zeit für das Erlernen der funktionalen Programmierung investieren möchten, ist Haskell wahrscheinlich der einzige, der diese Anforderungen erfüllt. Alle anderen, die ich kenne, wie Erlang, Scala, Clojure usw., bieten nur funktionale Abstraktionen über einer imperativen Sprache. Wenn Sie sich also dem funktionalen Paradigma in kleinen Schritten nähern möchten, würde ich Scala oder Erlang empfehlen. Wenn Sie alles auf einmal angehen und möglicherweise frustriert aufgeben möchten, sollten Sie sich für Haskell entscheiden.
quelle
Ich würde den gegenwärtigen Anstieg von Interessen in funktionalen Sprachen auf die Tatsache zurückführen, dass sie sich ideal für paralleles Rechnen eignen. Beispielsweise basiert die gesamte Idee der Kartenreduzierung auf einem Funktionsparadigma. Und es besteht kein Zweifel, dass das parallele Rechnen zunehmen wird, da klar ist, dass das derzeitige Scale-out viel einfacher und billiger ist als das Scale-up. Auch auf dem Consumer-Markt bekommen CPUs mehr Kerne, nicht mehr GHz.
EDIT: da es nicht für alle offensichtlich ist.
In der reinen Funktionsprogrammierung nimmt eine Funktion Eingaben auf, erzeugt Ausgaben und hat keine Nebenwirkungen. Keine Nebenwirkung bedeutet, dass kein gemeinsamer Status vorliegt und daher keine Synchronisationsmechanismen erforderlich sind, die andernfalls bei gleichzeitiger Ausführung erforderlich wären. Die Synchronisation ist der schwierigste Teil einer gleichzeitigen / parallelen Software. Wenn Sie also eine reine Funktionssoftware einsetzen, müssen Sie sich im Grunde genommen nicht mit dem schwierigsten Teil befassen.
Bei der Kartenreduzierung stammt sogar der Name aus der funktionalen Programmierung (sowohl die Zuordnung als auch die Reduzierung sind typische Operationen im funktionalen Paradigma). Beide Schritte der Kartenreduzierung sind Funktionen, die parallel ablaufen, Eingaben entgegennehmen, Ausgaben produzieren und keine Nebenwirkungen haben. Das ist also genau die rein funktionale Programmieridee.
Einige Beispiele für FP, die für Parallelität verwendet werden:
quelle