Características funcionales
No existe un límite claro de lo que define la programación funcional o una biblioteca funcional. Algunas características de los lenguajes funcionales están integradas en Javascript:
- Funciones de primera clase y de orden superior
- Funciones Lambdas / Anónimas, con cierres
Otros son posibles de lograr en Javascript con cierto cuidado:
- Inmutabilidad
- Transparencia referencial
Otros son parte de ES6 y están disponibles total o parcialmente en este momento:
- Funciones compactas, incluso concisas
- Recursividad performante a través de la optimización de la cola
Y hay muchos otros que están realmente más allá del alcance normal de Javascript:
- La coincidencia de patrones
- Evaluación perezosa
- Homoiconicidad
Una biblioteca, entonces, puede elegir qué tipo de características está tratando de admitir y aún así, razonablemente, llamarse "funcionales".
Especificación de la tierra de la fantasía
Fantasy-land es una especificación para varios tipos estándar transferidos desde la teoría de categorías matemáticas y el álgebra abstracta a la programación funcional, tipos como Monoid , Functor y Monad . Estos tipos son bastante abstractos y amplían posiblemente nociones más familiares. Los functores, por ejemplo, son contenedores que se pueden map
sobrepasar con una función, de la misma forma en que se puede map
sobrepasar una matriz Array.prototype.map
.
Cuento popular
Folktale es una colección de tipos que implementan varias partes de la especificación Fantasy-land y una pequeña colección de funciones de utilidad complementarias. Estos tipos son cosas como Quizás , O bien , Tarea (muy similar a lo que en otros lugares se llama Futuro y un primo más legal de una Promesa) y Validación
Folktale es quizás la implementación más conocida de la especificación Fantasy-land, y es muy respetada. Pero no existe una implementación definitiva o predeterminada; Fantasy-land solo especifica tipos abstractos, y una implementación, por supuesto, debe crear tales tipos concretos. La afirmación de Folktale de ser una biblioteca funcional es clara: proporciona tipos de datos que se encuentran típicamente en lenguajes de programación funcionales, que hacen que sea sustancialmente más fácil programar de manera funcional.
Este ejemplo, de la documentación de Folktale ( nota : no en las versiones recientes de los documentos), muestra cómo podría usarse:
// 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 (descargo de responsabilidad: soy uno de los autores) es un tipo de biblioteca muy diferente. No le proporciona nuevos tipos. 1 En cambio, proporciona funciones para facilitar la operación en tipos existentes. Se basa en las nociones de componer funciones más pequeñas en funciones más grandes, de trabajar con datos inmutables, de evitar efectos secundarios.
Ramda opera especialmente en listas, pero también en objetos y, a veces, en cadenas. También delega muchas de sus llamadas de tal manera que interoperará con Folktale u otras implementaciones de Fantasy-land. Por ejemplo, la map
función de Ramda opera de manera similar a la de encendido Array.prototype
, entonces R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
. Pero debido a que Folktale's Maybe
implementa la Functor
especificación Fantasy-land , que también especifica el mapa, también puedes usar la de Ramda map
con ella:
R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
Las afirmaciones de Ramda de ser una biblioteca funcional radican en facilitar la composición de funciones, nunca mutar sus datos y presentar solo funciones puras. El uso típico de Ramda sería desarrollar funciones más complejas componiendo funciones más pequeñas, como se ve en un artículo sobre la filosofía 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]
);
Otras bibliotecas
En realidad encontré más bibliotecas, todas parecen caer en las dos categorías. subrayado, lodash son muy parecidos a Ramda. La tierra de la fantasía, la fantasía sin sentido son como un cuento popular.
Eso no es realmente exacto. En primer lugar, Fantasy-land es simplemente una especificación que las bibliotecas pueden decidir implementar para varios tipos. Folktale es una de las muchas implementaciones de esa especificación, probablemente la mejor completa, sin duda una de las más maduras. Pointfree-fantasy y ramda-fantasy son otros, y hay muchos más .
Subrayado y lodash son superficialmente como Ramda en el sentido de que son bibliotecas de bolsa de mano, que proporcionan una gran cantidad de funciones con mucha menos cohesión que algo como Folktale. E incluso la funcionalidad específica a menudo se superpone con la de Ramda. Pero a un nivel más profundo, Ramda tiene preocupaciones muy diferentes de esas bibliotecas. Primos más cercanos de Ramda son probablemente las bibliotecas como FKit , Fnuc y Wu.js .
Bilby está en una categoría propia, proporcionando tanto una serie de herramientas como las proporcionadas por Ramda como algunos tipos compatibles con Fantasy-land. (El autor de Bilby es el autor original de Fantasy-land también).
Tu llamada
Todas estas bibliotecas tienen derecho a ser llamadas funcionales, aunque varían mucho en el enfoque funcional y el grado de compromiso funcional.
Algunas de estas bibliotecas funcionan bien juntas. Ramda debería funcionar bien con Folktale u otras implementaciones de Fantasy-land. Dado que sus preocupaciones apenas se superponen, realmente no entran en conflicto, pero Ramda hace lo suficiente para que la interoperación sea relativamente fluida. Esto probablemente sea menos cierto para algunas de las otras combinaciones que podría elegir, pero la sintaxis de función más simple de ES6 también puede aliviar parte del dolor de la integración.
La elección de la biblioteca, o incluso el estilo de la biblioteca a utilizar, dependerá de su proyecto y sus preferencias. Hay muchas buenas opciones disponibles, y los números están creciendo y muchas de ellas están mejorando enormemente. Es un buen momento para hacer programación funcional en JS.
1 Bueno, hay un proyecto paralelo, ramda-fantasy que hace algo similar a lo que hace Folktale, pero no es parte de la biblioteca principal.