Ich bin seit einiger Zeit Webentwickler und habe vor kurzem angefangen, funktionale Programmierung zu lernen. Wie andere hatte ich einige erhebliche Probleme, viele dieser Konzepte auf meine berufliche Arbeit anzuwenden. Für mich ist der Hauptgrund dafür, dass ein Konflikt zwischen dem Ziel von FP, staatenlos zu bleiben, ziemlich im Widerspruch zu der Tatsache steht, dass die meisten meiner Webentwicklungsarbeiten stark an Datenbanken gebunden waren, die sehr datenorientiert sind.
Eine Sache, die mich auf der OOP-Seite zu einem viel produktiveren Entwickler machte, war die Entdeckung objektrelationaler Mapper wie MyGeneration d00dads für .Net, Class :: DBI für Perl, ActiveRecord für Ruby usw. Dadurch konnte ich mich fernhalten vom Schreiben von Insert- und Select-Anweisungen den ganzen Tag über bis hin zum einfachen Arbeiten mit den Daten als Objekte. Natürlich konnte ich immer noch SQL-Abfragen schreiben, wenn ihre Leistung benötigt wurde, aber ansonsten wurde sie hinter den Kulissen schön abstrahiert.
Wenn wir uns nun der funktionalen Programmierung zuwenden, scheint es, als müssten bei vielen FP-Webframeworks wie Links wie in diesem Beispiel viel SQL-Code auf der Boilerplate geschrieben werden . Weblocks scheint ein wenig besser zu sein, aber es scheint eine Art OOP-Modell für die Arbeit mit Daten zu verwenden, und es muss weiterhin wie in diesem Beispiel für jede Tabelle in Ihrer Datenbank manuell Code geschrieben werden . Ich nehme an, Sie verwenden eine Codegenerierung, um diese Zuordnungsfunktionen zu schreiben, aber das scheint entschieden un-lisp-artig zu sein.
(Hinweis: Ich habe Weblocks oder Links nicht besonders genau betrachtet. Ich verstehe möglicherweise nur falsch, wie sie verwendet werden.)
Die Frage ist also, dass wir für die Datenbankzugriffsteile (von denen ich glaube, dass sie ziemlich groß sind) der Webanwendung oder für andere Entwicklungen, die eine Schnittstelle mit einer SQL-Datenbank erfordern, gezwungen sind, einen der folgenden Pfade einzuschlagen:
- Verwenden Sie keine funktionale Programmierung
- Greifen Sie auf lästige, nicht abstrahierte Weise auf Daten zu, indem Sie viel SQL oder SQL-ähnlichen Code ala Links manuell schreiben
- Erzwingen Sie unsere funktionale Sprache in ein Pseudo-OOP-Paradigma und entfernen Sie so einen Teil der Eleganz und Stabilität einer echten funktionalen Programmierung.
Natürlich scheint keine dieser Optionen ideal zu sein. Hat ein Weg gefunden, diese Probleme zu umgehen? Gibt es hier wirklich überhaupt ein Problem?
Hinweis: Ich persönlich kenne LISP im FP-Bereich am besten. Wenn Sie also Beispiele nennen und mehrere FP-Sprachen kennen möchten, ist Lisp wahrscheinlich die bevorzugte Sprache
PS: Zu Problemen, die für andere Aspekte der Webentwicklung spezifisch sind, siehe diese Frage .
quelle
Antworten:
Zunächst würde ich nicht sagen, dass CLOS (Common Lisp Object System) "Pseudo-OO" ist. Es ist erstklassig OO.
Zweitens glaube ich, dass Sie das Paradigma verwenden sollten, das Ihren Bedürfnissen entspricht.
Sie können Daten nicht zustandslos speichern, während eine Funktion ein Datenfluss ist und keinen Status benötigt.
Wenn Sie mehrere Bedürfnisse vermischt haben, mischen Sie Ihre Paradigmen. Beschränken Sie sich nicht darauf, nur die untere rechte Ecke Ihrer Toolbox zu verwenden.
quelle
Wenn ich dies aus der Sicht einer Datenbankperson betrachte, finde ich, dass Front-End-Entwickler sich zu sehr bemühen, Wege zu finden, um Datenbanken an ihr Modell anzupassen, anstatt die effektivsten Wege zur Verwendung von Datenbanken in Betracht zu ziehen, die nicht objektorientiert oder funktional, sondern relational und nutzbar sind Mengenlehre. Ich habe gesehen, dass dies im Allgemeinen zu einer schlechten Leistung des Codes führt. Außerdem wird Code erstellt, der nur schwer auf die Leistung abgestimmt werden kann.
Bei der Betrachtung des Datenbankzugriffs gibt es drei Hauptaspekte: Datenintegrität (warum alle Geschäftsregeln auf Datenbankebene und nicht über die Benutzeroberfläche durchgesetzt werden sollten), Leistung und Sicherheit. SQL wurde geschrieben, um die ersten beiden Überlegungen effektiver zu verwalten als jede Front-End-Sprache. Weil es speziell dafür entwickelt wurde. Die Aufgabe einer Datenbank unterscheidet sich stark von der Aufgabe einer Benutzeroberfläche. Ist es ein Wunder, dass die Art von Code, die bei der Verwaltung der Aufgabe am effektivsten ist, konzeptionell unterschiedlich ist?
Und Datenbanken enthalten Informationen, die für das Überleben eines Unternehmens entscheidend sind. Es ist kein Wunder, dass Unternehmen nicht bereit sind, mit neuen Methoden zu experimentieren, wenn ihr Überleben auf dem Spiel steht. Viele Unternehmen sind nicht einmal bereit, auf neue Versionen ihrer vorhandenen Datenbank zu aktualisieren. Das Datenbankdesign weist also einen inhärenten Konservatismus auf. Und das ist bewusst so.
Ich würde nicht versuchen, T-SQL zu schreiben oder Datenbankdesignkonzepte zum Erstellen Ihrer Benutzeroberfläche zu verwenden. Warum sollten Sie versuchen, Ihre Schnittstellensprache und Designkonzepte für den Zugriff auf meine Datenbank zu verwenden? Weil Sie denken, SQL ist nicht schick (oder neu) genug? Oder fühlen Sie sich damit nicht wohl? Nur weil etwas nicht zu dem Modell passt, mit dem Sie sich am wohlsten fühlen, heißt das nicht, dass es schlecht oder falsch ist. Es bedeutet, dass es anders ist und wahrscheinlich aus einem legitimen Grund anders. Sie verwenden ein anderes Werkzeug für eine andere Aufgabe.
quelle
Sie sollten sich die Zeitung "Out of the Tar Pit" von Ben Moseley und Peter Marks ansehen, die hier erhältlich ist: "Out of the Tar Pit" (6. Februar 2006)
Es ist ein moderner Klassiker, der ein Programmierparadigma / -system namens Functional-Relational Programming beschreibt. Obwohl es sich nicht direkt um Datenbanken handelt, wird erläutert, wie Interaktionen mit der Außenwelt (z. B. Datenbanken) vom Funktionskern eines Systems isoliert werden können.
In diesem Artikel wird auch erläutert, wie ein System implementiert wird, bei dem der interne Status der Anwendung mithilfe einer relationalen Algebra definiert und geändert wird, die offensichtlich mit relationalen Datenbanken zusammenhängt.
Dieses Dokument gibt keine genaue Antwort auf die Integration von Datenbanken und funktionaler Programmierung, hilft Ihnen jedoch beim Entwurf eines Systems zur Minimierung des Problems.
quelle
Funktionale Sprachen haben nicht das Ziel, staatenlos zu bleiben, sie haben das Ziel, die Verwaltung des Staates explizit zu machen. In Haskell können Sie beispielsweise die Staatsmonade als das Herz des "normalen" Zustands und die E / A-Monade als eine Darstellung des Zustands betrachten, der außerhalb des Programms existieren muss. Mit diesen beiden Monaden können Sie (a) zustandsbehaftete Aktionen explizit darstellen und (b) zustandsbehaftete Aktionen erstellen, indem Sie sie mit referenziell transparenten Werkzeugen zusammenstellen.
Sie verweisen auf eine Reihe von ORMs, die gemäß ihrem Namen abstrakte Datenbanken als Objektgruppen darstellen. Dies ist wirklich nicht das, was die Informationen in einer relationalen Datenbank darstellen! Gemäß seinem Namen repräsentiert es relationale Daten. SQL ist eine Algebra (Sprache) zum Behandeln von Beziehungen in einem relationalen Datensatz und ist selbst ziemlich "funktional". Ich spreche dies an, um zu berücksichtigen, dass (a) ORMs nicht die einzige Möglichkeit sind, Datenbankinformationen abzubilden, (b) dass SQL für einige Datenbankdesigns tatsächlich eine ziemlich nette Sprache ist und (c) dass funktionale Sprachen häufig eine relationale Algebra haben Zuordnungen, die die Leistungsfähigkeit von SQL auf idiomatische (und im Fall von Haskell typgeprüfte) Weise offenlegen.
Ich würde sagen, die meisten Lisps sind die funktionale Sprache eines armen Mannes. Es ist in der Lage, gemäß modernen funktionalen Praktiken verwendet zu werden, aber da es sie nicht erfordert, ist es weniger wahrscheinlich, dass die Community sie verwendet. Dies führt zu einer Mischung von Methoden, die sehr nützlich sein können, aber sicherlich verdecken, wie reine funktionale Schnittstellen Datenbanken noch sinnvoll nutzen können.
quelle
Ich denke nicht, dass die Staatenlosigkeit von fp-Sprachen ein Problem beim Herstellen einer Verbindung zu Datenbanken ist. Lisp ist eine nicht reine funktionale Programmiersprache, daher sollte es keine Probleme mit dem Status geben. Und reine funktionale Programmiersprachen wie Haskell haben Möglichkeiten, mit Ein- und Ausgaben umzugehen, die auf die Verwendung von Datenbanken angewendet werden können.
Aus Ihrer Frage geht hervor, dass Ihr Hauptproblem darin besteht, einen guten Weg zu finden, um die auf Datensätzen basierenden Daten, die Sie aus Ihrer Datenbank zurückerhalten, in etwas zu abstrahieren, das lisp-y (lisp-ish?) Ist, ohne viel SQL schreiben zu müssen Code. Dies scheint eher ein Problem mit den Werkzeugen / Bibliotheken als ein Problem mit dem Sprachparadigma zu sein. Wenn Sie reine FP machen möchten, ist Lisp möglicherweise nicht die richtige Sprache für Sie. Common Lisp scheint mehr mit der Integration guter Ideen aus oo, fp und anderen Paradigmen zu tun zu haben als mit reinem fp. Vielleicht sollten Sie Erlang oder Haskell verwenden, wenn Sie den reinen FP-Weg gehen möchten.
Ich denke, die 'Pseudo-Oo'-Ideen in Lisp haben auch ihren Wert. Vielleicht möchten Sie sie ausprobieren. Wenn sie nicht der Art und Weise entsprechen, wie Sie mit Ihren Daten arbeiten möchten, können Sie versuchen, über Weblocks eine Ebene zu erstellen, mit der Sie mit Ihren Daten nach Ihren Wünschen arbeiten können. Dies ist möglicherweise einfacher, als alles selbst zu schreiben.
Haftungsausschluss: Ich bin kein Lisp-Experte. Ich interessiere mich hauptsächlich für Programmiersprachen und habe mit Lisp / CLOS, Scheme, Erlang, Python und ein bisschen Ruby gespielt. Im täglichen Programmierleben bin ich immer noch gezwungen, C # zu verwenden.
quelle
Wenn Ihre Datenbank keine Informationen zerstört, können Sie auf funktionale Weise mit ihnen arbeiten, die mit "rein funktionalen" Programmierwerten übereinstimmen, indem Sie Funktionen der gesamten Datenbank als Wert bearbeiten.
Wenn zum Zeitpunkt T in der Datenbank angegeben ist, dass "Bob Suzie mag", und Sie eine Funktion hatten, die eine Datenbank und einen Liker akzeptiert, haben Sie ein reines Funktionsprogramm, das eine Datenbank umfasst, solange Sie die Datenbank zum Zeitpunkt T wiederherstellen können . z.B
Um dies zu tun, können Sie niemals Informationen wegwerfen, die Sie möglicherweise verwenden (was praktisch bedeutet, dass Sie keine Informationen wegwerfen können), sodass Ihr Speicherbedarf monoton ansteigt. Sie können jedoch beginnen, mit Ihrer Datenbank als lineare Reihe diskreter Werte zu arbeiten, wobei nachfolgende Werte durch Transaktionen mit den vorherigen Werten in Beziehung gesetzt werden.
Dies ist beispielsweise die Hauptidee von Datomic .
quelle
Überhaupt nicht. Es gibt ein Genre von Datenbanken, die als "funktionale Datenbanken" bekannt sind Mnesia vielleicht das am besten zugängliche Beispiel ist. Das Grundprinzip ist, dass die funktionale Programmierung deklarativ ist, damit sie optimiert werden kann. Sie können einen Join mithilfe von Listenverständnissen implementieren für persistente Sammlungen und der Abfrageoptimierer kann automatisch herausfinden, wie der Festplattenzugriff implementiert wird.
Mnesia ist in Erlang geschrieben und es gibt mindestens ein Webframework ( Erlyweb ) für diese Plattform. Erlang ist von Natur aus parallel zu einem Threading-Modell ohne gemeinsame Nutzung und eignet sich daher in gewisser Weise für skalierbare Architekturen.
quelle
Eine Datenbank ist der perfekte Weg, um den Status in einer zustandslosen API zu verfolgen. Wenn Sie REST abonnieren, besteht Ihr Ziel darin, zustandslosen Code zu schreiben, der mit einem Datenspeicher (oder einem anderen Backend) interagiert, der die Statusinformationen auf transparente Weise verfolgt, damit Ihr Client dies nicht muss.
Die Idee eines objektrelationalen Mappers, bei dem Sie einen Datenbankeintrag als Objekt importieren und dann ändern, ist für die funktionale Programmierung ebenso anwendbar und nützlich wie für die objektorientierte Programmierung. Die einzige Einschränkung besteht darin, dass durch die funktionale Programmierung das vorhandene Objekt nicht geändert wird. Mit der Datenbank-API können Sie jedoch den vorhandenen Datensatz ändern . Der Kontrollfluss Ihres Kunden würde ungefähr so aussehen:
Die Datenbank aktualisiert den Datensatz mit Ihren Änderungen. Eine reine funktionale Programmierung erlaubt möglicherweise keine Neuzuweisung von Variablen im Rahmen Ihres Programms , aber Ihre Datenbank-API kann weiterhin direkte Aktualisierungen zulassen.
quelle
Ich fühle mich mit Haskell am wohlsten. Das bekannteste Haskell-Webframework (vergleichbar mit Rails und Django) heißt Yesod. Es scheint ein ziemlich cooles, typsicheres Multi-Backend-ORM zu haben. Schauen Sie sich das Kapitel Ausdauer in ihrem Buch an.
quelle
Datenbanken und funktionale Programmierung können zusammengeführt werden.
beispielsweise:
Clojure ist eine funktionale Programmiersprache, die auf der Theorie relationaler Datenbanken basiert.
Hinweis: In der neuesten Spezifikation2 ähnelt die Spezifikation eher RMDB. sehen: spec-alpha2 wiki: Schema-and-select
Ich befürworte: Erstellen eines relationalen Datenmodells auf der Grundlage einer Hash-Map, um eine Kombination aus NoSQL- und RMDB-Vorteilen zu erzielen. Dies ist eigentlich eine umgekehrte Implementierung von posgtresql.
Ententypisierung: Wenn es wie eine Ente aussieht und wie eine Ente quakt, muss es eine Ente sein.
Wenn das Datenmodell von clojure wie eine RMDB, die Funktionen von clojure wie eine RMDB und die Datenmanipulation von clojure wie eine RMDB ist, muss clojure eine RMDB sein.
Clojure ist eine funktionale Programmiersprache, die auf der Theorie relationaler Datenbanken basiert
Alles ist RMDB
Implementieren Sie ein relationales Datenmodell und eine Programmierung basierend auf Hash-Map (NoSQL).
quelle