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 map
przerzucić za pomocą funkcji, tak jak tablica może być map
przerzucona 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 map
funkcja 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 Maybe
implementuje specyfikację Fantasy-land Functor
, która określa również mapę, możesz również użyć map
z 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.