Mentale Modelle oder reale Metaphern für die funktionale Programmierung

16

Hat jemand ein gutes mentales Modell oder eine Metapher für funktionale Programmierung, die sich auf etwas in der realen Welt bezieht?

Objektorientiertes Programmieren macht für mich intuitiv Sinn. Es gibt Dinge, die Eigenschaften haben, und manchmal können sie auch Dinge tun oder Berechnungen an ihren Eigenschaften (Methoden) durchführen. (Bsp .: Auto, Form, Katze).

Ich trage funktionale Programmierung und bin nicht an einer Debatte über die Tugenden der beiden interessiert. Ich brauche nur eine Metapher oder ein mentales Modell, um damit zu arbeiten, wie ich es bei der objektorientierten Programmierung getan habe.

Was sind gute mentale Modelle oder reale Metaphern für die Programmierung in einem funktionalen Paradigma? Es gibt etwas an Funktionen, die aus Funktionen bestehen, die Funktionen verarbeiten, und die einen keinen festen Platz zum Stehen und Nachdenken lassen.

Guido Anselmi
quelle
Auf welche konkrete Bedeutung von "funktionaler Programmierung" beziehen Sie sich, "keine Nebenwirkungen / deklarativ" oder "erstklassige Funktionen / Funktionszusammensetzung"? Oder beides?
aktueller
Interessante Frage. Mit meinen derzeitigen geringen Kenntnissen und meiner geringen Erfahrung im Programmieren in der "funktionalen Programmierung" kann ich diese Frage nicht sinnvoll beantworten. Wenn ich eine Vermutung anstellen würde, würde ich beides sagen.
Guido Anselmi
13
Das "reale" Modell wird oft als Motivation für objektorientiertes Programmieren angegeben. Ich denke, es ist ein Ansatz, über den Sie irgendwann hinauswachsen sollten, da Objekte in OOP nicht immer realen Objekten entsprechen sollten, und selbst wenn dies der Fall ist, ist die Korrespondenz oft unvollständig. Zum Beispiel sind die "is-a" -Beziehungen nicht immer gleich. Auf der anderen Seite, wenn Sie sagen, dass Sie ein Modell oder eine Metapher für eine Programmiersprache wollen, die auf etwas in der "realen Welt" basiert, haben Sie sich meiner Meinung nach im Wesentlichen auf diese begrenzte Form von OOP beschränkt.
David K
Ein wirklich gutes mentales Modell, wenn Sie Erfahrung mit Unix-ähnlichen Systemen (oder der PowerShell in modernen Windows) haben, sind Shell-One-Liner. Sie sind nicht genau gleich, da Shell-Pipes nicht funktional, sondern technisch flussbasiert programmiert werden, aber sie haben das gleiche "Gefühl" wie ein Programmierer.
Slebetman
1
Außerdem werden Sie feststellen, dass beim Erlernen funktionaler Sprachen die objektorientierte Programmierung wie ein Werkzeug behandelt wird, beispielsweise reguläre Ausdrücke. Etwas, das Sie verwenden können, wenn Sie möchten, aber nicht müssen. In einigen Sprachen wie lisp und tcl ist OO keine in die Sprache integrierte Funktion, sondern eine Bibliothek, die Sie verwenden können (oder Sie können sogar Ihr eigenes OO schreiben, wenn Sie sich mutig fühlen). So können Probleme, die natürlich eine OO-Lösung haben, mit OO in den meisten funktionalen Sprachen gelöst werden. Die Leute behandeln OO einfach nicht als Religion.
Slebetman

Antworten:

32

Bei der funktionalen Programmierung geht es darum, kleinere Funktionen zusammenzukleben, um Ihre Ergebnisse zu erzielen. Ein anständiges mentales Modell (zumindest für mich) ist ein Fließband. Jede Funktion, die zusammengestellt wird, ist ein weiterer Schritt im Montageprozess. Betrachten Sie diese Funktion hier:

smallest  = head . sort

In Haskell gibt diese Funktion das kleinste Element in einer Liste zurück. Die Fertigungslinie sortiert zuerst die Eingabe und gibt dann das erste Element zurück (vorausgesetzt, es wird vom kleinsten zum größten Element sortiert). Wenn wir nur den kleinsten geraden Wert erhalten möchten, können wir die Fertigungslinie folgendermaßen ändern:

smallestEven = head . sort . filter even

Es ist nur noch ein Schritt auf dem Förderband.

Kurz gesagt, beschreiben Funktionen nur die Schritte, die unternommen wurden, um den Roh-Input (die Teile) in das verarbeitete Gut (den Output) umzuwandeln.

bstamour
quelle
2
In einer reinen funktionalen Sprache ohne globale Variablen kann eine Fertigungslinie die andere nicht beeinflussen (es sei denn, sie speist die andere Linieneingabe.) Theoretisch können alle Fertigungslinien, die nicht voneinander abhängig sind, parallel ausgeführt werden, ich jedoch nicht Stellen Sie sicher, dass Compiler dies tun.
bstamour
3
@GuidoAnselmi Eine Möglichkeit, darüber nachzudenken, besteht darin, dass die Assembly-Line in der funktionalen Programmierung neue Ausgaben erstellt, während die Eingaben intakt bleiben, während die Assembly-Line in der traditionellen OOP die Eingabe transformiert.
Doval
2
Diese Metapher ist nur in der Bedeutung "Erstklassige Funktionen / Funktionszusammensetzung" von "Funktionsprogrammierung" sinnvoll, nicht in der Bedeutung "Keine Nebenwirkungen / Deklarativ". Die objektorientierte Programmierung hat nicht unbedingt Nebenwirkungen, sodass Sie entweder eine destruktive oder eine konstruktive Fertigungslinie mit OOP oder dieser Bedeutung von FP implementieren können. Bei OOP geht es mehr um Kapselung, Weitergabe von Nachrichten und Polymorphismus als um Nebenwirkungen. Es kommt darauf an, wie Sie Dinge modellieren. Benötigen Sie beispielsweise von Anfang bis Ende eine referenzielle Identität?
aktueller
3
@bstamour: Um genau zu sein, sollte man das (f . g) (x)Mittel f(g(x))oder die f . gMittel schreiben \x -> f (g (x)).
Giorgio
3
@MarjanVenema Die Dinge fließen in diesem Beispiel nur, weil das so .definiert ist. So funktioniert Haskell im Allgemeinen nicht . Sie könnten genauso gut den Forward-Pipe-Operator ( |>) von F # in Haskell definieren und schreiben, smallest x = (sort x) |> headund die Daten würden richtig fließen. Ich dachte nur, ich würde darauf hinweisen.
Doval
18

Hat jemand ein gutes mentales Modell für funktionale Programmierung?

Mathematik. Die funktionale Programmierung ist von der Mathematik inspiriert und an diese angelehnt. Mathematische Funktionen haben keinen Zustand, keine Nebenwirkungen usw., und so ist es auch mit FP. Wenn Sie über FP in Bezug auf mathematische Funktionen nachdenken, anstatt einen OO-ähnlichen Ansatz zu verwenden, sind Sie in guter Verfassung. Wenn Sie versuchen, FP mit OO-Sensibilität zu versorgen, schwimmen Sie gegen den Strom.

Caleb
quelle
1
Vielen Dank. Ich benötige jedoch eine Metapher aus der realen Welt (zB nicht von Computern oder Mathematik).
Guido Anselmi
3
@ GuidoAnselmi: Eine Funktion ist eine Blackbox. Sie legen etwas in die eine Seite und dann kommt etwas Neues auf die andere Seite. Wenn Sie dasselbe Material einsetzen, bekommen Sie immer dasselbe heraus. Sie können viele dieser Kästchen nehmen und sie in verschiedenen Reihenfolgen kombinieren, um eine Fabrik zu bauen, die Rohmetalle aufnehmen und ein Auto ausgeben kann. Das Innere des Prozesses ist in viele Teile zerlegt, aber von außen ist es nur eine andere Funktion.
Daenyth
16

Wie wäre es mit einem Daumenkino ?

In einem Daumenkino repräsentiert jede Seite die Welt, wie sie zu einem bestimmten Zeitpunkt existiert. In unserem Programm wird die Welt als eine zusammengesetzte Datenstruktur dargestellt (z. B. haben wir eine Banane, die in der Hand eines Gorillas liegt, der sich in einem Baum befindet, der sich in einem Dschungel befindet). Jede nachfolgende Seite erweitert die Story, indem die vorherige Darstellung leicht geändert wird. In FP wurden persistente Datenstrukturen entworfen, um vorherige Strukturen effizient wiederzuverwenden, sodass eine Änderung nur ein Delta und keine vollständig neue Wiedergabe bereitstellt.

Was möglicherweise nicht offensichtlich ist, ist, dass eine Seite in unserem Daumenkino auch immaterielle Werte darstellen würde. Wenn der Gorilla zum Beispiel die Banane fallen lässt, können wir damit beginnen, die Auswirkungen der Schwerkraft auf seine Anständigkeit und Beschleunigung in Richtung des Dschungelbodens anzuwenden. Um dem entgegenzukommen, würden wir unserer Banane Attribute wie Geschwindigkeit und Flugbahn hinzufügen.

In unserem Programm gibt es eine Funktion, die eine Flipbook-Seite (alias den Zustand der Welt) als Argument akzeptiert und eine neue Seite liefert . Auf diese Weise wird unsere Geschichte erzählt, ohne den Zustand bestehender Objekte zu verändern. Wir ersetzen einfach jede Seite durch eine neuere, wobei eine effektive Berechnung verwendet wird.

Mario T. Lanza
quelle
3

Beziehungen.

Freund: Bei zwei Personen folgt eine Freundschaft diesen allgemeinen Gesetzen

  1. Habe guten Willen zueinander
  2. Denkt, dass sich die beiden Freunde sind (daher müssen die Gesetze in dieser Beziehung von beiden Mitgliedern eingehalten werden)
  3. Genießt es, Zeit miteinander zu verbringen

Monoid: Bei mehreren Elementen und einer Funktion, die 2 der Elemente annimmt und 1 zurückgibt, folgt eine monoidale Beziehung diesen allgemeinen Gesetzen

  1. Es gibt eines dieser Elemente (nur eines mit der Bezeichnung Identität), das mit einem anderen Element an die Funktion übergeben wird, um sicherzustellen, dass die Funktion immer das andere Element zurückgibt (0 + 1 = 1, daher ist 0 die Identität, wenn es sich bei den Elementen um Zahlen handelt, und Funktion ist Zusatz)
  2. Die Funktion kann keine Elemente bearbeiten oder zurückgeben, die nicht in dem Satz enthalten sind, mit dem sie eine monoidale Beziehung hat
  3. Die Funktion ist assoziativ und kann in gewisser Weise unabhängig von der Reihenfolge mit den Elementen verwendet werden. Dies bedeutet a * (b * c) = (a * b) * c, was besagt, dass Sie a mit dem Ergebnis von b * c oder c multiplizieren können durch das Ergebnis von a * b und das Ergebnis wird das gleiche sein, was Sie zuerst tun.

Bei der funktionalen Programmierung dreht sich alles um Verallgemeinerungen. Friend ist eine sehr allgemeine Beziehung, die in zahlreichen Szenarien zu sehen ist, aber in allen verschiedenen Formaten folgt sie im Allgemeinen den obigen Gesetzen.

Wenn Sie die Gesetze kennen, die die Beziehungen zwischen Dingen regeln, können Sie allgemeine Implementierungen erstellen, die auf jedem Format von Dingen mit dieser Art von Beziehung funktionieren. In der funktionalen Programmierung versuchen Sie, die Beziehungen zwischen Dingen zu identifizieren, damit sie allgemein klassifiziert und behandelt werden können.

Sie möchten eine Metapher aus der realen Welt? Sehen Sie sich an, wie die Dinge zusammenhängen, und versuchen Sie, allgemeine Gesetze zu ermitteln (wie in mehreren Szenarien, in denen andere als die Gesetze variieren können). Es gibt eine Beziehung zwischen einem Kassierer und einem Käufer in einem Geschäft, es gibt einige allgemeine Gesetze, Software wurde entwickelt, um die Ziele von Personen in dieser allgemeinen Beziehung in Bezug auf POS-Systeme zu erleichtern. Auf ähnliche Weise können Sie sich beim Schreiben Ihrer Software auf die Gesetze dieser Beziehungen verlassen, anstatt auf die spezifischen Einzelheiten einer Beziehungsinstanz, wenn Sie feststellen, dass diese allgemeinen Gesetze die Zusammenhänge bestimmen.

Jimmy Hoffa
quelle
2

Alles ist ein Wert, und Sie wenden Funktionen auf Werte an (dies können Funktionen sein), um neue Werte zu erzeugen, vorzugsweise ohne Nebenwirkungen.

Doval
quelle
Vielen Dank. Leider klingt das eher nach einer Beschreibung als nach einem mentalen Modell oder einer Metapher. Ich brauche eine Metapher aus der realen Welt (nicht von Computern).
Guido Anselmi
1
Wie Caleb betont , modelliert die funktionale Programmierung die Mathematik, nicht die reale Welt. Es kann die reale Welt durch die Linse der Mathematik modellieren, aber Sie werden wahrscheinlich keine Metapher finden, die Sie zufriedenstellt, weil FP das Konzept der Dinge mit einer beständigen Identität und einem veränderlichen Zustand meidet. Wenn Sie möchten, kann ich darauf hinweisen, wie OOP eine Zuordnung zu FP erstellt, aber das ist immer noch nicht die gewünschte Antwort.
Doval
Die Mathematik basiert jedoch auf der realen Welt. 1 Sonne, 9 Planeten. 2 Äpfel plus 2 Äpfel ergeben vier Äpfel.
Guido Anselmi
In der funktionalen Programmierung können Sie auch einen Typ für Sonnen, Planeten und Äpfel definieren, dann einen Wert vom Typ Sonne und 9 Werte vom Typ Planet erstellen und einen Zusatz für den Apfeltyp definieren.
Doval
3
@GuidoAnselmi du hast es komplett rückwärts, die Leute analysieren die reale Welt mit Mathematik, es hat keine Basis auf der realen Welt. Die Mathematik dient zur Analyse und Definition von Beziehungen zwischen allen möglichen Dingen, realen und nicht realen. 9 planets wendet man ein mathematisches Konstrukt (die Menge der natürlichen Zahlen) auf ein reales Konstrukt (Planeten) mit einer mathematischen Analysefunktion (count) an. Die reale Welt hat keine neun Planeten, sie hat das, was sie hat. Mathematik spricht lediglich von symbolischen Darstellungen von Dingen, bei denen die Symbole Beziehungen zueinander haben.
Jimmy Hoffa
1

Das Wichtigste bei der funktionalen Programmierung ist, dass alles ein Wert ist - selbst der Code selbst ist 'Werte'.

Das beste Beispiel für eine einfache funktionale Programmierumgebung ist das von allen bevorzugte Geschäftstool - die Tabellenkalkulation. Jede Zelle in der Tabelle enthält entweder Daten oder das Ergebnis einer Funktion. Darüber hinaus kann diese Funktion keine andere Zelle ändern.

Wenn man zu einer funktionalen Sprache wechselt , haben die Funktionen anstelle eines kartesischen Gitters aus A1und B42Namen. Das ist alles was es wirklich ist.

Es gibt andere Aspekte, die man darüber hinaus hinzufügen kann ... aber das ist die funktionale Programmierung im Kern. Man muss sich keine Gedanken über die Struktur von Listen oder die Gruppierung von Dingen machen. Bei der funktionalen Programmierung geht es darum, einen Wert an eine Funktion zu übergeben und einen Wert zurückzugewinnen, ohne irgendwo anders im Speicher herumzuspielen.

Das ist es. Funktionale Programmierung ist eine Tabellenkalkulation mit Namen anstelle eines Rasters.


quelle
0

Sie können sich funktionale Programmierung als Verhalten vorstellen . Ein Programm ist eine Beschreibung des Verhaltens, das der Computer ausführen soll. Funktionen sind die Grundeinheit des Verhaltens, und die Funktionszusammensetzung ist eine Möglichkeit, aus kleineren Verhaltensweisen größere Verhaltensweisen zu erstellen.

In OOP wird ein Codeobjekt soll sein , den Zustand eines Objekts in dem Problembereich; Sie ändert sich mit der Zeit, um Änderungen in diesem Domänenobjekt widerzuspiegeln. In FP steht ein Wert für den Status eines Domänenobjekts. es ändert sich nie, Sie erstellen einfach unterschiedliche Werte, um unterschiedliche Zustände darzustellen.

Ich finde das Funktionsmodell ein bisschen ehrlicher, was Computer tatsächlich tun - darstellen. Schließlich kann ich nicht einfach etwas new Tesla()aus der Luft zaubern . :)

Jon Purdy
quelle
-5

Sätze sind funktionaler als objektorientiert, vorausgesetzt, Sie unterteilen sie mehr oder weniger wie folgt ...

The brown cow is in the meadow across the deep river.

Also müssen wir die Hauptsätze und dann den Rest finden:

The cow (brown)
the meadow (across)
the river (deep)

Auf einmal:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Baum analysieren:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Sparsamkeit beeinflusst das funktionale Denken;

Hut ab vor Gottlieb Frege aus den 1890er Jahren, Alan Turing (entschiedungsprobleme) aus den 1930er Jahren, Noam Chomsky (1960er Jahre).

KTys
quelle
4
Dies ist eine verwirrende Erklärung, und ich kenne mich zunächst mit FP aus.
Daenyth
Sieht aus wie die Form von Lisp nachahmen, ohne die Bedeutung zu verstehen
Izkata