Frage

Ich brauche meinen Kopf helfen, um den Unterschied immer zwischen meinem aktuellen OOP Begriff des Zustandes und die Art und Weise wäre es in einer funktionalen Sprache wie Haskell oder Clojure erfolgen.

ein abgedroschen Beispiel zu verwenden, lassen Sie uns sagen, dass wir mit vereinfachten Bankkonto Objekte / structs / was auch immer zu tun hat. In einer OOP-Sprache, würde ich eine Klasse haben einen Verweis auf ein Bankkonto gehalten wird, die Instanzvariablen für Dinge wie Zinssatz haben würde, und Methoden wie setInterestRate (), die den Zustand des Objekts zu ändern und in der Regel nichts zurück. In sagen Clojure, würde ich ein Bankkonto Struktur (eine glorifizierte hashmap) haben, und spezielle Funktionen, die ein Bankkonto Parameter und andere Informationen nehmen, und gibt eine neue Struktur. Anstatt also den Zustand des ursprünglichen Objekts zu ändern, ich habe jetzt ein neues Geschäft mit den gewünschten Änderungen zurückgegeben wird.

Also ... was mache ich damit? Überschreibt jede Variable wurde Verweis auf das alte Bank-Konto? Wenn ja, hat die Vorteile gegenüber dem Stand verändernden OOP-Ansatz? Am Ende in beiden Fällen scheint es, man eine Variable, die das Objekt mit den notwendigen Änderungen verweist. Retardiert, wie ich bin, ich habe nur eine vage Vorstellung davon, was vor sich geht.

Ich hoffe, dass Sinn gemacht, vielen Dank für jede Hilfe!

War es hilfreich?

Lösung

In einem reinen funktionalen Stil, werden Sie nie eine Variable überschreiben.

Eine Analogie zu Raum-Zeit in der Physik wäre. Wenn Sie die Welt als 3D betrachten, dann Objekte sind keine festen Positionen - sie bewegen sich im Laufe der Zeit. Um Mathe zu bringen auf der physischen Welt zu tragen, fügen wir daher eine zeitliche Dimension und berücksichtigen die Werte verschiedener Eigenschaften zu bestimmten Zeiten. Dabei haben wir die Objekte unserer Studie in Konstanten gemacht. Ebenso in der Programmierung gibt es eine konzeptionelle Einfachheit durch die Arbeit mit unveränderlichen Werten werden mußte. Objekte mit einer Identität in der realen Welt können (bei steigenden Zeiten der Zustände des Objekts) als eine Folge von unveränderlichen Werten modelliert werden und nicht als ein einzelnen Wert, ändert.

Natürlich sind die Details, wie die Folge von Werten zu einer „Objektidentität“ assoziieren kann ein wenig behaart sein. Haskell hat Monaden , die Sie Modellzustand lassen. Functional Reactive Programming ist ein wörtlichen Versuch Modellierungsobjekte in der Welt mit rein funktionalem Updates, dass ich denkt, ist eine vielversprechende Richtung für die Programmierung.

Ich werde beachten Sie, dass Clojure, im Gegensatz zu Haskell, nicht rein ist, und Sie können Variablen aktualisieren, wie Sie vorgeschlagen. Wenn Sie nur ein paar Variablen auf einem hohen Niveau zu aktualisieren, werden Sie wahrscheinlich immer noch viele der konzeptionellen Einfachheit Vorteile der funktionalen Programmierung genießen.

Andere Tipps

Vermutlich in der OO Welt haben Sie eine Schleife und werden diese Bankkonten immer und immer wieder als Reaktion auf Anfragen zu modifizieren. Nehmen wir an, Sie ein ganzes Portfolio von Konten haben und diese Art Portfolio haben. Dann in Haskell würden Sie eine reine Funktion schreiben

updatePortfolio :: Request -> Portfolio -> Portfolio

Und Ihre Hauptschleife könnte Anfragen von der Standardeingabe lesen und Ihren Portfolio aktuell halten. (Das Beispiel ist nicht viel, wenn Sie auch das Portfolio schreiben können, aber es ist einfacher.)

readRequest :: IO Request  -- an action that, when performed, reads a Request with side effects

main :: Portfolio -> IO ()  -- a completely useless program that updates a Portfolio in response to a stream of Requests

main portfolio = do req <- readRequest
                    main (updatePortfolio req)

und jetzt ich hoffe, dass Sie sehen, was Ihr wandelbaren Zustand passiert: in einem typischen Funktionsprogramm, das seinen Zustand ändert wird als Parameter an eine Funktion übergeben. Wenn der Zustand changess, stellen Sie einen neuen Funktionsaufruf. Der Aufruf ist in tail Position (man kann ‚richtigen Endaufruf‘ nachschlagen) und so hat es keine zusätzlichen Mittel verwenden, und in der Tat, wenn der Compiler erzeugt Assembler-Code eine Schleife erzeugt, und es wird den Zeiger auf dem halten sich ständig verändernden Portfolio in einem Register.

Dies ist ein sehr Spielzeug Beispiel, aber ich hoffe, dass es Ihnen ein wenig von dem Geschmack einer funktionalen Sprache gibt.

So ... was mache ich damit? Überschreiben Sie was auch immer Variable wurde Verweis auf die alte Bank-Konto?

Ja

Wenn ja, hat die Vorteile gegenüber dem Stand verändernden OOP-Ansatzes?

Nehmen wir an, die Berechnung jeglicher Aktion, die Sie auf dieser Struktur zu tun dauert eine lange Zeit und etwas passiert, auf halbem Weg, und Sie müssen wieder in die ursprüngliche Struktur oder die Berechnung wird eine Fehler zurückzukehren. Mit der Interpretation du mir von OO vorgestellt haben (mit einer Referenz, weil Sie eine unveränderliche OO Sprache haben kann), dass die Daten unbekannt korrupt --es der sein könnte, wenn nicht genügend Informationen aus dem ausgefallenen Funktionsaufruf gegeben wurde, und lässt vorschlagen es fehlgeschlagen schlecht. In einem funktionalen Ansatz wissen Sie sicher, dass Ihre ursprüngliche Datenstruktur korrekt ist --because Sie zunächst eine Kopie gemacht.

Erweitern Sie dieses Szenario in Multi-Threaded-Anwendungen. Wir können sicherstellen, dass niemand sonst die Datenstruktur verwendet wir sind, da wir alle unsere eigene Version davon haben.

Darüber hinaus können wir Platz sparen, indem Daten von der anderen Struktur verwenden, die wir kopieren aus. Ein klassisches Beispiel ist, wenn ein Element auf den Kopf einer Liste hinzugefügt wird. Wenn wir einen Zeiger auf das zweite Element haben, und einen Zeiger auf das erste Element wir nur die Größe der ersten beiden Listen mit Bezug kann (siehe unten). Ohne Unveränderlichkeit können wir dies nicht garantieren.

        b__
           |  
a -> [6|] -+-> [5|] -> [4|] -> [3|] -> [2|] -> [1|x]

Sehen Sie in Haskell, die eine reine funktionale Sprache-es ist keine Neuzuordnung auch immer, sowie keine anderen Nebenwirkungen: Um IO zu tun, in der IO Monade konstruieren ersetzt es tatsächlich die Real World mit einem neue Instanz der Welt, die, beispielsweise neuer Text angezeigt in der Konsole hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top