Caratteristiche funzionali
Non esiste un confine netto di ciò che definisce la programmazione funzionale o una libreria funzionale. Alcune caratteristiche dei linguaggi funzionali sono incorporate in Javascript:
- Funzioni di prima classe e di ordine superiore
- Funzioni Lambdas / Anonimo, con chiusure
Altri sono possibili da realizzare in Javascript con una certa cura:
- Immutabilità
- Trasparenza referenziale
Altri ancora fanno parte di ES6 e sono disponibili parzialmente o completamente al momento:
- Funzioni compatte, persino concise
- Ricorsione performante attraverso l'ottimizzazione della chiamata di coda
E ce ne sono molti altri che sono davvero oltre la normale portata di Javascript:
- Corrispondenza del modello
- Valutazione pigra
- Omoiconicità
Una libreria, quindi, può scegliere quali tipi di funzionalità sta cercando di supportare e ancora essere ragionevolmente chiamata "funzionale".
Specifica della terra di fantasia
Fantasy-land è una specifica per un certo numero di tipi standard portati dalla teoria matematica delle categorie e dall'algebra astratta alla programmazione funzionale, tipi come Monoid , Functor e Monad . Questi tipi sono abbastanza astratti ed estendono nozioni forse più familiari. I funtori, ad esempio, sono contenitori che possono essere map
trasferiti con una funzione, nello stesso modo in cui un array può essere map
utilizzato Array.prototype.map
.
Folktale
Folktale è una raccolta di tipi che implementano varie parti della specifica Fantasy-land e una piccola raccolta di funzioni di utilità complementare. Questi tipi sono cose come Forse , Entrambi , Attività (molto simile a quello che altrove è chiamato Futuro e un cugino più legale di una Promessa) e Convalida
Folktale è forse l'implementazione più nota della specifica Fantasy-land ed è ben rispettata. Ma non esiste un'implementazione definitiva o predefinita; fantasy-land specifica solo tipi astratti, e un'implementazione ovviamente deve creare tali tipi concreti. L'affermazione di Folktale di essere una libreria funzionale è chiara: fornisce tipi di dati che si trovano tipicamente nei linguaggi di programmazione funzionale, quelli che rendono sostanzialmente più facile programmare in modo funzionale.
Questo esempio, dalla documentazione di Folktale ( nota : non nelle versioni recenti dei documenti), mostra come potrebbe essere utilizzato:
// 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 (disclaimer: sono uno degli autori) è un tipo di libreria molto diverso. Non fornisce nuovi tipi per te. 1 Fornisce invece funzioni per semplificare le operazioni sui tipi esistenti. È costruito attorno alle nozioni di comporre funzioni più piccole in funzioni più grandi, di lavorare con dati immutabili, di evitare effetti collaterali.
Ramda opera soprattutto sugli elenchi, ma anche sugli oggetti e talvolta sulle stringhe. Delega anche molte delle sue chiamate in modo tale da interagire con Folktale o altre implementazioni di Fantasy-land. Ad esempio, la map
funzione di Ramda , funziona in modo simile a quella su Array.prototype
, quindi R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]
. Ma poiché Folktale Maybe
implementa la specifica Fantasy-land Functor
, che specifica anche la mappa, puoi anche usare Ramda's map
con essa:
R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing
Le affermazioni di Ramda di essere una libreria funzionale stanno nel rendere facile comporre funzioni, non mutare mai i dati e presentare solo funzioni pure. L'uso tipico di Ramda sarebbe costruire funzioni più complesse componendone di più piccole, come si vede in un articolo sulla filosofia di Ramda
// :: [Comment] -> [Number]
var userRatingForComments = R.pipe(
R.pluck('username') // [Comment] -> [String]
R.map(R.propOf(users)), // [String] -> [User]
R.pluck('rating'), // [User] -> [Number]
);
Altre biblioteche
In realtà ho trovato più librerie, sembrano tutte rientrare nelle due categorie. sottolineatura, i lodash sono molto simili a Ramda. La terra della fantasia, la fantasia senza punti sono come un racconto popolare.
Non è proprio accurato. Prima di tutto, Fantasy-land è semplicemente una specifica che le biblioteche possono decidere di implementare per vari tipi. Folktale è una delle tante implementazioni di quella specifica, probabilmente la più completa, sicuramente una delle più mature. La fantasia senza punti e la fantasia ramda sono altre, e ce ne sono molte altre .
Underscore e lodash sono superficialmente come Ramda in quanto sono librerie a portata di mano, che forniscono un gran numero di funzioni con molta meno coesione rispetto a qualcosa come Folktale. E anche la funzionalità specifica spesso si sovrappone a quella di Ramda. Ma a un livello più profondo, Ramda ha preoccupazioni molto diverse da quelle biblioteche. Cugini più stretti di Ramda sono probabilmente librerie come FKit , Fnuc , e Wu.js .
Bilby è in una categoria a sé stante, fornendo sia una serie di strumenti come quelli forniti da Ramda sia alcuni tipi coerenti con Fantasy-land. (L'autore di Bilby è anche l'autore originale di Fantasy-land.)
La tua chiamata
Tutte queste librerie hanno il diritto di essere chiamate funzionali, sebbene differiscano notevolmente nell'approccio funzionale e nel grado di impegno funzionale.
Alcune di queste librerie funzionano effettivamente bene insieme. Ramda dovrebbe funzionare bene con Folktale o altre implementazioni di Fantasy-land. Dal momento che le loro preoccupazioni si sovrappongono a malapena, in realtà non sono in conflitto, ma Ramda fa quel tanto che basta per rendere l'interoperabilità relativamente agevole. Questo è probabilmente meno vero per alcune delle altre combinazioni che potresti scegliere, ma la sintassi della funzione più semplice di ES6 potrebbe anche eliminare parte del problema dell'integrazione.
La scelta della libreria, o anche dello stile della libreria da utilizzare, dipenderà dal tuo progetto e dalle tue preferenze. Sono disponibili molte buone opzioni e i numeri stanno crescendo e molte di esse stanno migliorando notevolmente. È un buon momento per fare programmazione funzionale in JS.
1 Bene, c'è un progetto secondario , ramda-fantasy che fa qualcosa di simile a quello che fa Folktale, ma non fa parte della libreria principale.