Funktionsmerkmale
Es gibt keine klare Grenze für die Definition der funktionalen Programmierung oder einer funktionalen Bibliothek. Einige Funktionen funktionaler Sprachen sind in Javascript integriert:
- Erstklassige Funktionen höherer Ordnung
- Lambdas / Anonymous-Funktionen mit Verschlüssen
Andere sind in Javascript mit einiger Sorgfalt möglich:
- Unveränderlichkeit
- Referentielle Transparenz
Wieder andere sind Teil von ES6 und derzeit teilweise oder vollständig verfügbar:
- Kompakte, sogar knappe Funktionen
- Performante Rekursion durch Tail-Call-Optimierung
Und es gibt viele andere, die außerhalb der normalen Reichweite von Javascript liegen:
- Mustervergleich
- Faule Bewertung
- Homoikonizität
Eine Bibliothek kann dann auswählen, welche Arten von Funktionen sie unterstützen möchte, und dennoch vernünftigerweise als "funktional" bezeichnet werden.
Fantasy-Land-Spezifikation
Fantasy-Land ist eine Spezifikation für eine Reihe von Standardtypen, die von der mathematischen Kategorietheorie und der abstrakten Algebra bis zur funktionalen Programmierung portiert sind, wie Monoid , Functor und Monad . Diese Typen sind ziemlich abstrakt und erweitern möglicherweise bekanntere Begriffe. Funktoren sind beispielsweise Container, die map
mit einer Funktion überfahren werden können, so wie ein Array mit map
überfahren werden kann Array.prototype.map
.
Märchen
Folktale ist eine Sammlung von Typen, die verschiedene Teile der Fantasy-Land-Spezifikation implementieren, sowie eine kleine Sammlung von begleitenden Dienstprogrammfunktionen. Diese Typen sind Dinge wie Vielleicht , Entweder , Aufgabe (sehr ähnlich zu dem, was anderswo als Zukunft bezeichnet wird, und ein rechtmäßigerer Cousin eines Versprechens) und Validierung
Folktale ist vielleicht die bekannteste Implementierung der Fantasy-Land-Spezifikation und wird sehr geschätzt. Es gibt jedoch keine endgültige oder Standardimplementierung. Fantasy-Land spezifiziert nur abstrakte Typen, und eine Implementierung muss natürlich solche konkreten Typen erzeugen. Der Anspruch von Folktale, eine funktionale Bibliothek zu sein, ist klar: Es bietet Datentypen, die typischerweise in funktionalen Programmiersprachen zu finden sind und die das funktionale Programmieren wesentlich erleichtern.
Dieses Beispiel aus der Folktale-Dokumentation ( Hinweis : nicht in neueren Versionen der Dokumente) zeigt, wie es verwendet werden kann:
// We load the library by "require"-ing it
var Maybe = require('data.maybe')
// Returns Maybe.Just(x) if some `x` passes the predicate test
// Otherwise returns Maybe.Nothing()
function find(predicate, xs) {
return xs.reduce(function(result, x) {
return result.orElse(function() {
return predicate(x)? Maybe.Just(x)
: /* otherwise */ Maybe.Nothing()
})
}, Maybe.Nothing())
}
var numbers = [1, 2, 3, 4, 5]
var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers)
// => Maybe.Just(3)
var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers)
// => Maybe.Nothing
Ramda
Ramda (Haftungsausschluss: Ich bin einer der Autoren) ist eine ganz andere Art von Bibliothek. Es werden keine neuen Typen für Sie bereitgestellt. 1 Stattdessen bietet es Funktionen, die die Bedienung vorhandener Typen erleichtern. Es basiert auf dem Gedanken, kleinere Funktionen zu größeren zusammenzusetzen, mit unveränderlichen Daten zu arbeiten und Nebenwirkungen zu vermeiden.
Ramda arbeitet insbesondere mit Listen, aber auch mit Objekten und manchmal mit Strings. Es delegiert auch viele seiner Aufrufe so, dass es mit Folktale oder anderen Fantasy-Land-Implementierungen zusammenarbeitet. Zum Beispiel map
funktioniert Ramdas Funktion ähnlich wie die auf Array.prototype
, also R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
. Da Folktale's Maybe
jedoch die Fantasy-Land- Functor
Spezifikation implementiert , die auch die Karte spezifiziert, können Sie auch Ramdas map
damit verwenden:
R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
Ramdas Anspruch, eine funktionale Bibliothek zu sein, besteht darin, das Erstellen von Funktionen zu vereinfachen, Ihre Daten niemals zu mutieren und nur reine Funktionen zu präsentieren. Typische Verwendung von Ramda wäre der Aufbau komplexerer Funktionen durch Zusammensetzen kleinerer, wie in einem Artikel über die Philosophie von Ramda zu sehen ist
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
Andere Bibliotheken
Eigentlich habe ich mehr Bibliotheken gefunden, sie scheinen alle in die beiden Kategorien zu fallen. Lodash sind Ramda sehr ähnlich. Fantasy-Land, Pointfree-Fantasy sind wie Märchen.
Das ist nicht wirklich genau. Erstens ist Fantasy-Land einfach eine Spezifikation, die Bibliotheken für verschiedene Typen implementieren können. Folktale ist eine von vielen Implementierungen dieser Spezifikation, wahrscheinlich die am besten abgerundete, sicherlich eine der ausgereiftesten. Pointfree-Fantasy und Ramda-Fantasy sind andere, und es gibt noch viele mehr .
Unterstrich und Lodash sind oberflächlich wie Ramda, da sie Grab-Bag-Bibliotheken sind und eine große Anzahl von Funktionen mit viel weniger Zusammenhalt bieten als so etwas wie Folktale. Und selbst die spezifischen Funktionen überschneiden sich häufig mit denen von Ramda. Auf einer tieferen Ebene hat Ramda jedoch ganz andere Bedenken als diese Bibliotheken. Ramda engsten Verwandten sind wahrscheinlich Bibliotheken wie FKIT , Fnuc und Wu.js .
Bilby gehört zu einer eigenen Kategorie und bietet sowohl eine Reihe von Tools wie die von Ramda als auch einige Typen, die mit Fantasy-Land übereinstimmen. (Der Autor von Bilby ist auch der ursprüngliche Autor von Fantasy-Land.)
Ihr Anruf
Alle diese Bibliotheken haben das Recht, als funktional bezeichnet zu werden, obwohl sie sich in ihrem funktionalen Ansatz und dem Grad des funktionalen Engagements stark unterscheiden.
Einige dieser Bibliotheken arbeiten tatsächlich gut zusammen. Ramda sollte gut mit Folktale oder anderen Fantasy-Land-Implementierungen funktionieren. Da sich ihre Bedenken kaum überschneiden, stehen sie wirklich nicht in Konflikt, aber Ramda tut gerade genug, um die Interaktion relativ reibungslos zu gestalten. Dies gilt wahrscheinlich weniger für einige der anderen Kombinationen, die Sie auswählen können, aber die einfachere Funktionssyntax von ES6 kann auch die Integration erleichtern.
Die Wahl der Bibliothek oder sogar Stil der Bibliothek zu verwenden, wird auf Ihrem Projekt und Ihre Vorlieben ab. Es gibt viele gute Optionen, und die Anzahl wächst, und viele von ihnen verbessern sich erheblich. Es ist ein guter Zeitpunkt, um funktionale Programmierung in JS durchzuführen.
1 Nun, es gibt ein Nebenprojekt, eine Ramda-Fantasie , die etwas Ähnliches wie Folktale macht, aber nicht Teil der Kernbibliothek ist .