:sparkles: PWA :sparkles:
Twarz autora bloga

Piotr Kowalski

Organizator WarsawJS Trener YouTuber

Moja przygoda z monadami w JavaScript

Kilka lat temu mój kolega z pracy, developer pythona, który to uwielbiał czytać książki techniczne rozwijając przy tym swój wachlarz umiejętności zapytał mnie, osoby która zajmowała się JavaScript, jak to w "moim" języku wyglądają monady.

Baner reklamujący artykuł

Flame

Pierwsze co pomyślałem, to że znowu zaczyna się flame - czyli kolejna kłótnia, nad wyższością swojego języka programowania. Nie lubię brać udziału w takich dyskusjach, ponieważ zwykle poza zwiększeniem poziomu stresu niczego wartościowego nie doświadczymy.

Niestety zawiodłem, ponieważ nie znałem odpowiedzi na jego pytania.
Wtedy nie wiedziałem czym się charakteryzuje programowanie funkcyjne, tym samym coś takiego jak monady w JavaScript dla mnie nie istniały.

Generalnie po kilkudziesięciu minutach researchu dowiedziałem się, że monady to takie "idiotoodporne" funkcje. Gama metod biblioteki jQuery jest dobrym przykładem, które to nigdy (a raczej rzadko kiedy) rzucą wyjątku. Z takim myśleniem zostałem przez kolejne 2-3 lata.

Po 2 latach bycia niedoinformowanym...

Pewnego dnia mój kolega Michał Kawalec, zaprosił mnie na Monadic Warsaw. Mowa tu dokładnie o 6-tej edycji tego meetupa. Monadic to organizacja, której przyświeca cel rozmawiania o programowaniu funkcyjnym. Postanowiłem, że z miła chęcią się odwdzięczę i opowiem o monadach w JavaScript - doczytam, przygotuję się i wyjdę na scenę.

Poczytałem, przestudiowałem. Zrobiłem slajdy piecioshka.github.io/slides-monads-in-javascript/. Jestem przygotowany - do dzieła zatem!

Wychodzę na scenę

Przyszedłem na spotkanie. Pełna sala.

Świetnie jest widzieć tylu ludzi, którzy poza swoimi codziennymi obowiązkami przychodzą na spotkania i się rozwijają.

Po wysłuchaniu pierwszej prezentacji poprowadzonej przez Bartosza Milewskiego, który to wyjaśniał teorię kategorii, dowiedziałem się zdecydowanie więcej o monadach niż przypuszczałem.

Dowiedziałem się, że monada musi zawsze zwracać inny typ gdy zostanie zdefiniowany ze względu na swoją naturę. Monady to konstruktory typów. Dlatego gdy zostaną użyte muszę zwracać rożne wyniki.

jQuery to nie jest monada

Biblioteka jQuery, o której wcześniej pisałem nie jest więc przykładem na realizację monad w JavaScript.

Poniżej jeden z slajdów z mojej prezentacji: jQuery is not a monad

Źródła slajdów dostępne tu: github.com/piecioshka/slides-monads-in-javascript

Podczas swojego researchu przed prezentacją i kompletowaniem źródeł, z których korzystałem przy tworzeniu slajdów natknąłem się na post https://www.quora.com/Is-jQuery-a-monad. W pierwszym komentarzu mój poprzednik na scenie wyjaśnił, że wszyscy, którzy uważają jQuery za monadę, żyją w błędzie.

jQuery nie jest monadą, ponieważ gdy zastosujemy funkcję jQuery $() na wyniku tejże funkcji to otrzymamy ten sam typ obiektu.
$($($('body'))) jest tym samym co $('body').

Podczas mojego researchu dowiedziałem się o 3 aksjomatach, które muszą zostać spełnione, aby można było coś nazwać monadą.

3 prawa monad

Przetłumaczyłem prawa znajdujące się w projekcie github.com/piecioshka/my-monad#the-monadic-laws na język polski (z góry przepraszam jeśli się pomyliłem w tłumaczeniu).

  • monada jest wraperem na inny typ
  • wszystkie funkcje monad muszą posiadać funkcję do wrapowania samych siebie o inne typy danych
  • wszystkie monady muszą być zdolne aby zasilać wartością, które wrapują, inne funkcje, dopóki one nie zwrócą kolejnej monady

W czym monady pomagają?

Monady mają pomóc w programowaniu i to robią.
Najpopularniejszym przykładem monad jest obiekt Promise w JavaScript. To dzięki niemu piszemy kod asynchronicznych w sposób bardzo czytelny. Przykład:

function makeSomething(value) {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve(value), 1000);
    });
}

Promise.resolve(3)
    .then(makeSomething)
    .then((value) => {
        console.debug(value);
    });

Podsumowanie

Temat monad jest bardzo szeroki. Nie opisałem jak samemu stworzyć implementację chociażby Identity Monad, ze względu na to, że istnieje już wiele miejsc gdzie można takie implementację zobaczyć.
Na swoim profilu na GitHubie stworzyłem projekt, z implementacją monad w JavaScript. Zapraszam do odwiedzenia przykładowych testów: github.com/piecioshka/my-monad

Aby jeszcze bardziej zapoznać się monadami i ich różnymi typami zapraszam do 11 slajdu mojej prezentacji na Monadic Warsaw piecioshka.github.io/slides-monads-in-javascript/#11. Jest tutaj lista podstawowych typów monad jakie występują w przyrodzie.

Bibliografia

Na zakończenie warto zapoznać się ze źródłami, z których czerpałem wiedzę:

  1. Monads & Gonads - Douglas Crockford (GoogleTechTalks)
  2. Monads in JavaScript
  3. Brian Beckman: Don't fear the Monad
  4. Monads and Objects
  5. So simple MONAD implementation
  6. Step by step into Monads
  7. Use monads in JavaScript without needing to know how they work.
  8. jQuery is not a monad