Caractéristiques fonctionnelles
Il n'y a pas de limite claire de ce qui définit la programmation fonctionnelle ou une bibliothèque fonctionnelle. Certaines fonctionnalités des langages fonctionnels sont intégrées à Javascript:
- Fonctions de premier ordre et d'ordre supérieur
- Fonctions Lambdas / Anonymes, avec fermetures
D'autres sont possibles à réaliser en Javascript avec un certain soin:
- Immutabilité
- Transparence référentielle
D'autres encore font partie d'ES6 et sont partiellement ou entièrement disponibles pour le moment:
- Fonctions compactes, voire concises
- Récursivité performante grâce à l'optimisation des appels de fin
Et il y en a beaucoup d'autres qui sont vraiment hors de portée normale de Javascript:
- Correspondance de motif
- Évaluation paresseuse
- Homoiconicité
Une bibliothèque, alors, peut choisir les types de fonctionnalités qu'elle essaie de prendre en charge et toujours raisonnablement qualifiée de "fonctionnelle".
Spécification Fantasy-Land
Fantasy-terre est une spécification pour un certain nombre de types standards portés de la catégorie mathématique et théorie abstraite algèbre à la programmation fonctionnelle, types tels que Monoid , Functor et Monad . Ces types sont assez abstraits et étendent peut-être des notions plus familières. Les foncteurs, par exemple, sont des conteneurs qui peuvent être map
pédalés avec une fonction, comme un tableau peut être map
pédalé en utilisant Array.prototype.map
.
Conte folklorique
Folktale est une collection de types mettant en œuvre diverses parties de la spécification Fantasy-land et une petite collection de fonctions utilitaires complémentaires. Ces types sont des choses comme Peut - être , l'un ou l'autre , une tâche (très similaire à ce qu'on appelle ailleurs un avenir, et un cousin plus légitime d'une promesse), et la validation
Folktale est peut-être l'implémentation la plus connue de la spécification Fantasy-land, et elle est très respectée. Mais il n'existe pas d'implémentation définitive ou par défaut; fantasy-land ne spécifie que des types abstraits, et une implémentation doit bien sûr créer de tels types concrets. La prétention de Folktale d'être une bibliothèque fonctionnelle est claire: elle fournit des types de données que l'on trouve généralement dans les langages de programmation fonctionnels, ceux qui facilitent considérablement la programmation de manière fonctionnelle.
Cet exemple, tiré de la documentation Folktale ( note : pas dans les versions récentes de la documentation), montre comment il pourrait être utilisé:
// 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 (avertissement: je suis l'un des auteurs) est un type de bibliothèque très différent. Il ne fournit pas de nouveaux types pour vous. 1 Au lieu de cela, il fournit des fonctions pour faciliter l'utilisation des types existants. Il est construit autour des notions de composition de fonctions plus petites en fonctions plus grandes, de travail avec des données immuables, d'éviter les effets secondaires.
Ramda opère surtout sur les listes, mais aussi sur les objets, et parfois sur les chaînes. Il délègue également plusieurs de ses appels de manière à interagir avec Folktale ou d'autres implémentations Fantasy-land. Par exemple, la map
fonction de Ramda fonctionne de la même manière que celle sur Array.prototype
, donc R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
. Mais comme Folktale Maybe
implémente la Functor
spécification Fantasy-land , qui spécifie également la carte, vous pouvez également utiliser Ramda map
avec:
R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
Les prétentions de Ramda à être une bibliothèque fonctionnelle consistent à faciliter la composition de fonctions, à ne jamais muter vos données et à ne présenter que des fonctions pures. L'utilisation typique de Ramda serait de construire des fonctions plus complexes en composant des plus petites, comme on le voit dans un article sur la philosophie de Ramda
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
Autres bibliothèques
En fait, j'ai trouvé plus de bibliothèques, elles semblent toutes tomber dans les deux catégories. soulignement, lodash est très similaire à Ramda. Fantasy-land, pointfree-fantasy sont comme des contes populaires.
Ce n'est pas vraiment exact. Tout d'abord, Fantasy-land est simplement une spécification que les bibliothèques peuvent décider d'implémenter pour différents types. Folktale est l'une des nombreuses implémentations de cette spécification, probablement la meilleure, certainement l'une des plus matures. Pointfree-fantasy et ramda-fantasy en sont d'autres, et il y en a bien d'autres .
Underscore et lodash sont superficiellement comme Ramda en ce qu'ils sont des bibliothèques à saisir, fournissant un grand nombre de fonctions avec beaucoup moins de cohésion que quelque chose comme Folktale. Et même la fonctionnalité spécifique chevauche souvent celle de Ramda. Mais à un niveau plus profond, Ramda a des préoccupations très différentes de celles de ces bibliothèques. Cousins les plus proches de Ramda sont probablement des bibliothèques comme Fkit , FNUC et Wu.js .
Bilby est dans une catégorie à part, fournissant à la fois un certain nombre d'outils tels que ceux fournis par Ramda et certains types compatibles avec Fantasy-land. (L'auteur de Bilby est également l'auteur original de Fantasy-land.)
Ton appel
Toutes ces bibliothèques ont le droit d'être qualifiées de fonctionnelles, même si leur approche fonctionnelle et leur degré d'engagement fonctionnel varient considérablement.
Certaines de ces bibliothèques fonctionnent en fait bien ensemble. Ramda devrait bien fonctionner avec Folktale ou d'autres implémentations Fantasy-land. Étant donné que leurs préoccupations se chevauchent à peine, elles ne sont vraiment pas en conflit, mais Ramda en fait juste assez pour rendre l'interopération relativement fluide. C'est probablement moins vrai pour certaines des autres combinaisons que vous pourriez choisir, mais la syntaxe de fonction plus simple d'ES6 peut également soulager une partie de la douleur de l'intégration.
Le choix de la bibliothèque, voire du style de bibliothèque à utiliser, dépendra de votre projet et de vos préférences. Il existe de nombreuses options intéressantes, et les chiffres augmentent, et bon nombre d'entre elles s'améliorent considérablement. C'est le bon moment pour faire de la programmation fonctionnelle dans JS.
1 Eh bien, il y a un projet parallèle , ramda-fantasy qui fait quelque chose de similaire à ce que fait Folktale, mais il ne fait pas partie de la bibliothèque principale.