From 4ce380d6b70a62cfb97ea0dd2dccf460ab7d0d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Sko=C5=99epa?= <jakub@skorepa.info> Date: Fri, 12 Aug 2016 20:24:09 +0200 Subject: [PATCH] =?UTF-8?q?P=C5=99id=C3=A1n=20=C4=8Dl=C3=A1nek=20Javascrip?= =?UTF-8?q?t:=20Funkcion=C3=A1ln=C3=AD=20programov=C3=A1n=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../javascript-funkcionalni-programovani.md | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 articles/2016/javascript-funkcionalni-programovani.md diff --git a/articles/2016/javascript-funkcionalni-programovani.md b/articles/2016/javascript-funkcionalni-programovani.md new file mode 100644 index 00000000..ae61ac80 --- /dev/null +++ b/articles/2016/javascript-funkcionalni-programovani.md @@ -0,0 +1,101 @@ +``` +title="Javascript: Kompozice a currying" +``` + +O funkcionálnĂm programovanĂ se Ĺ™Ăká (jako i o spoustÄ› jinĂ˝ch vÄ›cĂ), Ĺľe vám musĂ +takzvanÄ› "docvaknout", ale jakmile vám docvakne tak to zaÄŤne dávat smysl a vy +budete v programovánĂ mnohem lepšĂ. MyslĂm si, Ĺľe mi dnes nÄ›co z funkcionálnĂho +programovanĂ docvaklo. + +MÄ›jme následujĂcĂ jednoduchĂ˝ Ăşkol: VytvoĹ™te funkci která: +- Z pole na vstupu, napĹ™: `[1,2,3,4]` +- Vytvořà pole objektĹŻ `[{a: 1, b: 2}, {a: 3, b: 4}]` +- Tedy vezme dvojice prvkĹŻ z pole a vytvořà z nich objekt `{a, b}` + +Jak na to? ImperativnĂ zpĹŻsob by vypadal takto: + +``` +function transform(arr) { + var temp = [] + for(var i = 0; i < arr.length/2; i++) { + temp.push({a: arr[i*2], b: arr[i*2+1]}) + } + return temp +} + +transform([1,2,3,4]) +``` + +To nenĂ tak špatnĂ©, Ĺľe? Co se na tom dá zlepšit? ProblĂ©m je, Ĺľe to moc +nevyjadĹ™uje vÄ›tu "vezme dvojice prvkĹŻ z pole a vytvořà z nich objekt `{a, b}`". + +K pĹ™eloĹľenà části "vezme dvojice prvkĹŻ" lze s vĂ˝hodou pouĹľĂt funkce chunk +z~knihovny [lodash](https://lodash.com/). A k části "vytvořà z nich objekt" se +dá pouĹľĂt funkce map (aĹĄ uĹľ lodash nebo standardnĂ verze). PouĹľĂvám FP verzi +knihovny lodash. + +``` +function transform(arr) { + return _.chunk(2, arr).map(function(el) { + return {a: el[0], b[1]} + }) +} + +transform([1,2,3,4]) +``` + +Tento kĂłd uĹľ je lepšà co se ÄŤitelnosti týče. ÄŚte se takto "rozsekej pole arr na +podpole velikosti 2 (funkce `_.chunk`) a potom kaĹľdou tuto část nahraÄŹ polem +`{a,b}` (funkce `.map`)" + +Ale co by se stalo pokud bychom chtÄ›li pouĹľĂt funkci map z knihovny lodash? +To by potĂ© vypadalo následovnÄ›: + +``` +function transform(arr) { + return _.map(function(el) { + return {a: el[0], b[1]} + }, _.chunk(2, arr)) +} + +transform([1,2,3,4]) +``` + +Neboli "Namapuj to co vytvořà funkce `_.chunk(2, arr)`". Tomuto se Ĺ™Ăká kompozice +funkcĂ (function composition). Neboli jedna funkce dostane to, co druhá funkce +vracĂ. VytvářĂme tĂm takovĂ© pomyslnĂ© potrubĂ. `vstup -> chunk -> map -> vĂ˝stup`. +K tomuto se takĂ© dá pouĹľĂt funkce `_.flow` + +``` +var transform = _.flow( + _.chunk(2), + _.map((el)=> {return { + a:el[0], + b:el[1] + } +})) + +transform([1,2,3,4]) +``` + +Neboli pĹ™esnÄ› `vstup -> chunk -> map ([a,b] => {a,b}) -> vĂ˝stup`. Jak to ale funguje? + +Aby toto mohlo fungovat tak knihovna lodash (v FP verzi) implementuje koncept, +kterĂ©mu se Ĺ™Ăká 'currying'. Ten funguje tak, Ĺľe pokud funkce pĹ™ijĂmá nÄ›kolik +argumentĹŻ a my nÄ›kterĂ˝ vynecháme tak mĂsto aby provedla danou akci nám vrátĂ +funkci. + +DĹŻsledek tohoto je, Ĺľe `chunk(2, arr)` provede to samĂ© jako `chunk(2)(arr)` a to +je to samĂ© jako `var chunk2 = chunk(2); chunk(arr);`. Jednoduchá iplementace +funkce flow by vypadala takto: + +``` +function flow(a, b) { + return function(args) { + b(a(args)) + } +} +``` + +To je vše! Ukázali jsem si, jak implementovat stejnou funkci 4mi rĹŻznĂ˝mi zpĹŻsoby, +jak funguje currying a co je to kompozice funkcĂ. -- GitLab