Vorteile der zustandslosen Programmierung?
Ich habe seit kurzem das lernen über funktionale Programmierung (speziell Haskell, aber ich habe mich durch die tutorials auf Lisp und Erlang). Zwar fand ich die Konzepte sehr aufschlussreich, ich verstehe immer noch nicht, die praktische Seite von "keine Nebenwirkungen" - Konzept. Was sind die praktischen Vorteile der es? Ich versuche zu denken, in die funktionale Denkweise, aber es gibt einige Situationen, die scheinen gerade übermäßig Komplex, ohne die Möglichkeit zum speichern des Zustands in eine einfache Möglichkeit (ich denke nicht, dass Haskell - Monaden 'einfach').
Lohnt es sich, weiter zu lernen, Haskell (oder andere rein funktionale Sprache) in die Tiefe? Funktions-oder stateless-Programmierung tatsächlich produktiver als prozessuale? Ist es wahrscheinlich, dass ich weiterhin in Haskell oder einer anderen funktionalen Sprache später, oder sollte ich es lernen, nur die für das Verständnis?
Sorge ich mich weniger um Leistung als die Produktivität. So bin ich vor allem der Frage, ob ich produktiver in eine funktionale Sprache, die als eine prozedurale/objektorientierte/was auch immer.
InformationsquelleAutor der Frage Sasha Chedygov | 2009-05-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lesen Funktionale Programmierung in einer Nussschale.
Es gibt viele Vorteile für Staatenlose Programmierung, nicht zuletzt von denen ist dramatisch Multithread-und concurrent-code. Um es klar zu sagen, veränderlich Staat ist ein Feind des Multithread-code. Wenn die Werte unveränderlich sind standardmäßig Programmierer nicht brauchen, um über einen thread mutiert der Wert gemeinsamer Staat zwischen zwei threads, so beseitigt es eine ganze Klasse von multithreading-Fehler im Zusammenhang mit race conditions. Da gibt es keine race conditions, es gibt keinen Grund, zu sperren, also Unveränderlichkeit entfällt eine ganze Klasse von Fehlern im Bezug auf Verklemmungen, wie gut.
Das ist der große Grund, warum funktionale Programmierung-Angelegenheiten, und wahrscheinlich die beste, die für das springen auf der funktionalen Programmierung zu trainieren. Es gibt auch noch viele andere Vorteile, einschließlich Vereinfachtes debugging (d.h. Funktionen sind rein und nicht mutieren Zustand, in anderen teilen einer Anwendung), weitere knappe und ausdrucksstarke code, weniger boilerplate-code im Vergleich zu Sprachen, die sind stark abhängig von design-patterns, und der compiler kann mehr aggressiv optimieren Sie Ihren code.
InformationsquelleAutor der Antwort Juliet
Desto mehr Stücke des Programms sind staatenlos, je mehr Möglichkeiten es gibt, um die Stücke zusammen, ohne irgendetwas zu brechen. Die macht des stateless-Paradigma liegt nicht in der Staatenlosigkeit (oder Reinheit) per seaber die Fähigkeit es gibt, Sie zu schreiben, kraftvoll, wiederverwendbare Funktionen und kombinieren Sie.
Finden Sie eine gute Anleitung mit vielen Beispielen in John Hughes ' s Papier Warum Funktionale Programmierung Fragen (PDF).
Werden Sie gobs mehr produktiv, vor allem, wenn Sie Holen eine funktionale Sprache, die auch algebraische Datentypen und pattern matching (Caml, SML, Haskell).
InformationsquelleAutor der Antwort Norman Ramsey
Viele der anderen Antworten haben sich auf die Leistung (Parallelität) Seite der funktionalen Programmierung, die ich glaube, ist sehr wichtig. Allerdings hast du speziell Fragen über Produktivität, wie in, können Sie das Programm die gleiche Sache schneller in einem funktionalen Paradigma als in einer imperativen Paradigma.
Finde ich eigentlich (aus eigener Erfahrung), dass die Programmierung in F# stimmt, so denke ich, besser, und so ist es einfacher. Ich denke, das ist der größte Unterschied. Ich habe programmiert in beiden F# und C#, und es gibt viel weniger "Kampf gegen die Sprache", in F#, die ich Liebe. Sie müssen nicht denken, über die details in F#. Hier ein paar Beispiele von dem, was ich gefunden habe, die ich wirklich genieße.
Zum Beispiel, obwohl F# ist statisch typisiert (alle Arten aufgelöst werden zur compile-Zeit), die Typ-Inferenz findet heraus, welche Arten Sie haben, so dass Sie nicht haben, es zu sagen. Und wenn es es kann nicht herausfinden, macht er automatisch deine Funktion/Klasse/whatever Generika. So dass Sie nie zu schreiben generischen was auch immer, es ist alles automatisch. Ich finde, dass bedeutet, dass ich mehr Zeit damit verbringen, über das problem nachzudenken, und weniger, wie es zu implementieren. In der Tat, wenn ich kommen Sie zurück zu C#, ich finde, die ich wirklich vermisse diese Art der Inferenz, Sie nie merken, wie störend es ist, bis Sie nicht brauchen, um es nicht mehr tun.
Auch in F#, statt zu schreiben Schleifen Sie Funktionen aufrufen. Es ist eine subtile Veränderung, aber signifikant, weil Sie nicht haben, zu denken, das loop-Konstrukt nicht mehr. Für Beispiel, hier ist ein Stück code, das würde gehen durch und Spiel etwas (ich kann mich nicht erinnern, was, es ist aus einem Projekt Euler-puzzle):
Erkenne ich, dass ein filter dann eine Karte (das ist eine Konvertierung der einzelnen Elemente) in C# wäre ganz einfach, aber Sie haben zu denken, auf einem niedrigeren Niveau. Vor allem, man müsste schreiben Sie die loop selbst, und haben Ihre eigenen expliziten if-Anweisung, und diese Art von Dingen. Da das erlernen von F#, ich habe realisiert, dass ich gefunden habe, die es einfacher, code in der Funktions-Weise, wo Sie, wenn Sie filtern möchten, schreiben Sie "filter", und wenn Sie zuordnen möchten, schreiben Sie "Karte", statt der Umsetzung der einzelnen details.
Ich Liebe auch die |> Bediener, was ich denke, trennt F# von ocaml -, und möglicherweise andere funktionale Sprachen. Es ist der pipe-operator, können Sie die "pipe" die Ausgabe eines Ausdrucks in den Eingang des anderen Ausdruck. Es macht den code auch zu Folgen, wie ich glaube, mehr. Wie im code-snippet oben, das sagt, "nehmen Sie die Faktoren Sequenz, filtern, ordnen Sie es." Es ist eine sehr hohe Ebene des Denkens, die Sie nicht bekommen, in eine imperative Programmiersprache, weil Sie sind so beschäftigt, schreiben die Schleife und if-Anweisungen. Es ist die eine Sache, die ich am meisten vermissen, wenn ich gehe in eine andere Sprache.
Also nur im Allgemeinen, auch wenn ich das Programm in C# und F#, ich finde es einfacher zu verwenden, F# weil Sie denken können auf einer höheren Ebene. Ich würde argumentieren, dass, weil die kleineren details sind entnommen funktionale Programmierung (in F# zumindest), bin ich produktiver.
Bearbeiten: ich sah in einem der Kommentare, die Sie gebeten, ein Beispiel für "state" in einer funktionalen Programmiersprache. F# kann geschrieben werden muss, so ist hier eine direkte Beispiel, wie Sie mutable state in F#:
InformationsquelleAutor der Antwort Ray Hidayat
Betrachten alle der schwierigen bugs haben Sie verbrachte eine lange Zeit mit Debuggen.
Nun, wie viele von diesen "bugs" wurden aufgrund von "unbeabsichtigten Interaktionen" zwischen zwei verschiedenen Komponenten eines Programms? (Fast alle threading-bugs haben diese form: ein Rennen mit schreiben gemeinsame Daten, deadlocks, ... Außerdem ist es Häufig zu finden Bibliotheken, die einige unerwartete Wirkung auf den globalen Zustand, oder Lesen/schreiben der registry-Umgebung, etc.) Ich würde postulieren, dass mindestens 1 in 3 'schwere Fehler' fallen in diese Kategorie.
Nun, wenn Sie wechseln Sie zu Staatenlosen/unveränderliche/Reine Programmierung, alle diese Fehler Weg. Sie präsentiert sich mit einigen neuen Herausforderungen statt (z.B. wenn Sie tun möchte verschiedene Module zur Interaktion mit der Umwelt), aber in einer Sprache wie Haskell, diese Interaktionen Holen Sie sich explizit vergegenständlicht in das Typ-system, was bedeutet, dass Sie einfach nur Aussehen bei der Art der Funktion und den Grund, über die Art der Wechselwirkungen kann es mit dem rest des Programms.
Das ist der große Sieg von der 'Unveränderlichkeit' IMO. In einer idealen Welt würden wir alle design tolles APIs und selbst wenn die Dinge wurden verändert, die Auswirkungen sind lokal und gut dokumentiert ist, und 'unvorhergesehene' Wechselwirkungen würden auf ein minimum reduziert werden. In der realen Welt gibt es zahlreiche APIs, die die Interaktion mit globalen Zustand in vielfältiger Weise, und diese sind die Quelle der schlimmsten bugs. Anstreben der Staatenlosigkeit ist angehende Los zu sein, unbeabsichtigte/implizite/hinter-den-kulissen " - Interaktionen zwischen den Komponenten.
InformationsquelleAutor der Antwort Brian
Einer der Vorteile von stateless Funktionen ist, dass Sie erlauben oder caching Vorberechnung der Funktion Werte zurückgeben. Auch einige C-Compiler erlauben Sie explizit markieren Funktionen, die als Staatenlose zu verbessern Ihre optimisability. Wie viele andere haben darauf hingewiesen, zustandslose Funktionen sind viel einfacher zu parallelise.
Aber die Effizienz ist nicht die einzige Sorge. Eine Reine Funktion ist einfacher zu testen und zu Debuggen, da alles, was das betrifft, es ist explizit angegeben. Und bei der Programmierung in einer funktionalen Sprache, bekommt man in der Gewohnheit, da einige Funktionen "schmutzig" (mit I/O, etc.) wie möglich. Die Trennung der stateful Zeug auf diese Weise ist ein guter Weg, um ein Programm zu entwerfen, auch in nicht-so-funktionalen Sprachen.
Funktionalen Sprachen kann eine Weile dauern, zu "bekommen", und es ist schwer zu erklären für jemanden, der noch nicht Durchlaufen diesen Prozess. Aber die meisten Menschen, die lange genug bestehen, endlich erkennen, dass die Aufregung ist es Wert, auch wenn Sie am Ende nicht mit funktionalen Sprachen viel.
InformationsquelleAutor der Antwort Artelius
Ohne Staat, es ist sehr einfach, um automatisch code parallelisieren (als CPUs mit immer mehr Kernen ist dies sehr wichtig).
InformationsquelleAutor der Antwort Zifre
Schrieb ich einen Beitrag über eben dieses Thema eine Weile zurück: Auf Die Bedeutung der Reinheit.
InformationsquelleAutor der Antwort naasking
Stateless web-Anwendungen sind unerlässlich, wenn Sie beginnen mit einem höheren Verkehrsaufkommen.
Könnte es viele Benutzer Daten, die Sie nicht speichern wollen, auf der client-Seite aus Gründen der Sicherheit zum Beispiel. In diesem Fall müssen Sie, um es zu speichern auf server-Seite. Sie könnten die web-Anwendungen Standard-Sitzung, aber wenn Sie mehr als eine Instanz der Anwendung, die Sie benötigen, um sicherzustellen, dass jeder Benutzer zielt immer auf die gleiche Instanz.
Load Balancer haben oft die Fähigkeit zu haben, "sticky sessions", wo der Lastenausgleich einige, wie weiß, welche server für das senden der Nutzer-Anfrage zu. Das ist nicht ideal, obwohl zum Beispiel jedes mal, wenn Sie starten Sie Ihren web-Anwendung, die alle Benutzer verlieren Ihre Sitzung.
Ein besserer Ansatz ist es, speichern Sie die Sitzung, die hinter der web-Server in eine Art von Daten speichern, in diesen Tagen gibt es jede Menge tolle nosql-Produkte zur Verfügung (redis, mongo, elasticsearch, memcached). Diese Art der web-Server zustandslos sind, aber Sie haben noch state-server-Seite und die Verfügbarkeit dieser Staat verwaltet werden können, durch die Wahl der richtigen datastore-setup. Diese speichert die Daten in der Regel haben große Redundanz, so dass Sie sollte fast immer möglich sein, um änderungen an Ihrer web-Anwendung und sogar die Daten speichern, ohne Auswirkungen auf die Benutzer.
InformationsquelleAutor der Antwort shmish111