Funkcje funkcjonalne
Nie ma wyraźnej granicy tego, co definiuje programowanie funkcjonalne lub bibliotekę funkcjonalną. Niektóre funkcje języków funkcjonalnych są wbudowane w Javascript:
- Funkcje pierwszorzędne, wyższego rzędu
- Funkcje Lambdy / Anonymous z zamknięciami
Inne są możliwe do wykonania w JavaScript z pewną ostrożnością:
- Niezmienność
- Referencyjna przejrzystość
Jeszcze inne są częścią ES6 i są teraz częściowo lub w pełni dostępne:
- Kompaktowe, a nawet zwięzłe funkcje
- Wydajna rekurencja dzięki optymalizacji wywołań ogonowych
Jest też wiele innych, które są naprawdę poza normalnym zasięgiem Javascript:
- Dopasowanie wzorców
- Leniwa ocena
- Homoikoniczność
Biblioteka może więc wybierać, jakie rodzaje funkcji próbuje obsługiwać i nadal rozsądnie nazywać ją „funkcjonalną”.
Specyfikacja krainy fantasy
Fantasy-land to specyfikacja wielu standardowych typów przeniesionych z matematycznej teorii kategorii i algebry abstrakcyjnej do programowania funkcjonalnego, takich jak Monoid , Functor i Monad . Te typy są dość abstrakcyjne i rozszerzają prawdopodobnie bardziej znane pojęcia. Na przykład funktory to kontenery, które można mapprzerzucić za pomocą funkcji, tak jak tablica może być mapprzerzucona za pomocą funkcji Array.prototype.map.
Folktale
Folktale to zbiór typów implementujących różne części specyfikacji Fantasy-land oraz niewielki zbiór towarzyszących funkcji użytkowych. Typy te są rzeczy podoba Może , albo , zadanie (bardzo podobny do tego, co gdzie indziej nazywa się przyszłości, a bardziej legalny kuzyn obietnicę), a Validation
Folktale jest prawdopodobnie najbardziej znaną implementacją specyfikacji Fantasy-land i cieszy się dużym uznaniem. Ale nie ma czegoś takiego jak ostateczna lub domyślna implementacja; Fantasy-land określa tylko typy abstrakcyjne, a implementacja musi oczywiście tworzyć takie konkretne typy. Twierdzenie Folktale o byciu biblioteką funkcjonalną jest jasne: dostarcza typów danych spotykanych zwykle w funkcjonalnych językach programowania, które znacznie ułatwiają programowanie w sposób funkcjonalny.
Ten przykład z dokumentacji Folktale ( uwaga : nie w ostatnich wersjach dokumentacji) pokazuje, jak można go użyć:
var Maybe = require('data.maybe')
function find(predicate, xs) {
return xs.reduce(function(result, x) {
return result.orElse(function() {
return predicate(x)? Maybe.Just(x)
: Maybe.Nothing()
})
}, Maybe.Nothing())
}
var numbers = [1, 2, 3, 4, 5]
var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers)
var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers)
Ramda
Ramda (zastrzeżenie: jestem jednym z autorów) to zupełnie inny rodzaj biblioteki. Nie zapewnia nowych typów. 1 Zamiast tego zapewnia funkcje ułatwiające obsługę istniejących typów. Opiera się na pojęciach łączenia mniejszych funkcji w większe, pracy z niezmiennymi danymi, unikania skutków ubocznych.
Ramda działa szczególnie na listach, ale także na obiektach, a czasami na łańcuchach. Przekazuje również wiele swoich wywołań w taki sposób, że będzie współpracować z Folktale lub innymi implementacjami Fantasy-land. Na przykład mapfunkcja Ramdy działa podobnie do funkcji na Array.prototype, więc R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]. Ale ponieważ Folktale Maybeimplementuje specyfikację Fantasy-land Functor, która określa również mapę, możesz również użyć mapz nią Ramdy :
R.map(square, Maybe.Just(5));
R.map(square, Maybe.Nothing);
Ramda twierdzi, że jest biblioteką funkcjonalną, ponieważ ułatwia tworzenie funkcji, nigdy nie mutuje danych i przedstawia tylko czyste funkcje. Typowym zastosowaniem Ramdy byłoby zbudowanie bardziej złożonej funkcji poprzez komponowanie mniejszych, jak widać w artykule o filozofii Ramdy
var userRatingForComments = R.pipe(
R.pluck('username')
R.map(R.propOf(users)),
R.pluck('rating'),
);
Inne biblioteki
Właściwie znalazłem więcej bibliotek, wszystkie wydają się należeć do dwóch kategorii. podkreślenie, lodash są bardzo podobne do Ramdy. Fantasy-land, pointfree-fantasy są jak legenda.
To nie jest do końca dokładne. Przede wszystkim Fantasy-land to po prostu specyfikacja, którą biblioteki mogą zdecydować się zaimplementować dla różnych typów. Folktale to jedna z wielu implementacji tej specyfikacji, chyba najlepiej dopracowana, na pewno jedna z najbardziej dojrzałych. Pointfree-fantasy i ramda-fantasy to inne, a jest ich znacznie więcej .
Podkreślenie i lodash są z pozoru podobne do Ramdy, ponieważ są bibliotekami typu `` grab-bag '', dostarczającymi wielu funkcji o znacznie mniejszej spójności niż coś takiego jak Folktale. A nawet specyficzna funkcjonalność często pokrywa się z Ramdą. Ale na głębszym poziomie Ramda ma zupełnie inne obawy niż te biblioteki. Najbliższymi kuzynami Ramdy są prawdopodobnie biblioteki takie jak FKit , Fnuc i Wu.js .
Bilby to osobna kategoria, która zapewnia zarówno szereg narzędzi, takich jak te dostarczone przez Ramdę, jak i niektóre typy zgodne z Fantasy-land. (Autor Bilby jest również oryginalnym autorem Fantasy-landu.)
Twoja decyzja
Wszystkie te biblioteki mają prawo nazywać się funkcjonalnymi, chociaż różnią się znacznie podejściem funkcjonalnym i stopniem zaangażowania funkcjonalnego.
Niektóre z tych bibliotek dobrze ze sobą współpracują. Ramda powinna dobrze współpracować z Folktale lub innymi implementacjami Fantasy-land. Ponieważ ich obawy ledwie się pokrywają, tak naprawdę nie są ze sobą sprzeczne, ale Ramda robi wszystko, co w ich mocy, aby zapewnić stosunkowo płynną współpracę. Jest to prawdopodobnie mniej prawdziwe w przypadku niektórych innych kombinacji, które możesz wybrać, ale prostsza składnia funkcji ES6 może również zmniejszyć ból związany z integracją.
Wybór biblioteki, a nawet stylu biblioteki będzie zależał od projektu i preferencji. Dostępnych jest wiele dobrych opcji, a ich liczba rośnie, a wiele z nich znacznie się poprawia. To dobry czas na programowanie funkcjonalne w JS.
1 Cóż, istnieje poboczny projekt, ramda-fantasy, który robi coś podobnego do tego, co robi Folktale, ale nie jest częścią podstawowej biblioteki.