Vysvětlení konceptů funkčního programovacího paradigmatu

Tenhle bude docela jiný, až vstoupíme na neprobádaná území...

...no, pokud jde o obsah našeho blogu.

Žádný JAMstack, žádné rámce JavaScript.

Dokonce opouštíme sféru objektově orientovaného programování.

Jsem opravdu rád, že s vámi mohu demystifikovat téma, kterým jsem byl v poslední době posedlý, abych byl docela upřímný.

Toto je přehled paradigmatu funkčního programování .

V tomto díle chci prozkoumat některé základní koncepty a základní myšlenky za tím. Koncepty, které můžete začít aplikovat hned teď na většinu programovacích jazyků.

Pokusím se to na této cestě ilustrovat, aby to šlo co nejplynuleji.

Opravdu doufám, že vás to nadchne stejně jako mě tím, co může funkční paradigma přinést budoucnosti vývoje webu.

Odmítnutí odpovědnosti :V žádném případě nejsem expert na funkční programování. S tímto paradigmatem jsem stále na začátku, protože jsem se s ním začal mísit teprve před rokem a půl. Zpočátku vám to bude pravděpodobně připadat tajemné, ale mějte se mnou strpení, protože bych upřímně považoval funkčnost za jeden z největších průlomů v mém logickém myšlení.

Takže bez dalšího žertování, pojďme do toho.

Co je funkcionální programování?

Říkejme tomu FP, pro skvělé děti.

Buďme líní, protože FP miluje lenost, a definujme předmět pomocí citátu:

— Brian Lonsdorf

I když je tato definice tak meta, jak jen může být, tato definice začne dávat stále větší smysl, jak si osvojíte styl FP.

Kromě toho, že tento citát pochází od Briana Lonsdorfa, velkého funkčního evangelisty, je převzat z předmluvy "Functional Light JS", knihy od JS guru Kyle Simpsona. Pokud jste webový vývojář a chcete se naučit FP seriózně, měla by to být vaše první kniha.

Pokud to myslíte opravdu vážně a snažíte se najít čas, abyste se naučili FP, přestaňte číst tento příspěvek (ty bláho) a začněte místo toho číst tuto knihu, jako ve skutečnosti.

Základní koncepty funkčního paradigmatu

Ve skutečnosti se nedotkneme žádných hlubokých akademických matematických kořenů FP, to je něco, do čeho byste se mohli přirozeně ponořit, pokud se nakonec chopíte paradigmatu, ale nemyslím si, že to je nyní nutné.

Spíše se zaměříme na pojmy, které lze aplikovat na většinu programovacích jazyků. Díky tomu jej již můžete začít používat každý den, postupně.

Funkce nejsou takové, jaké si myslíte, že jsou

Než se pustím do něčeho konkrétního, chci vás připravit na některé základy pojmu „funkce“ v FP. Funkce v FP je mnohem přísnější než klasická definice, kterou byste získali pomocí imperativního paradigmatu.

Pokud jste nikdy nedělali FP, je pravděpodobné, že vám to zní pravdivě:

No, už ne kamaráde. Od této chvíle byste měli k funkcím přistupovat více matematicky.

Matematický přístup?

V matematické funkci neexistuje žádný rozsah ani globální stav. Vedle vstupních proměnných nelze získat přístup k žádným informacím .

Což znamená, že když napíšete f(x) =x^2 na kus papíru, na písčitou půdu Marsu nebo definujete funkci na počítači, vždy se to vyhodnotí jako 25 pro x =5.

Pokud toho dosáhnete, skončíte se všemi magickými výhodami matematického světa (nápověda; je toho mnohem víc, než si myslíte).

Funkce by měla být čistá

Čistý znamená, že při stejných vstupech by funkce měla vždy vrátit stejný výstup, je to deterministické.

Klademe důraz na vždy znovu. Znamená to, že tyto nejsou považovány za čisté:

  • IO operace

  • Webové požadavky,

  • Cokoli, co může vyvolat výjimku

Nyní některé čistě funkční programovací jazyky jako Haskell budou toto pravidlo vynucovat, zatímco některé jsou flexibilnější. Možná se ptáte, co bude proboha účelem vašeho programu, když nemůžete udělat všechno z toho. No, odpověď je, že ve skutečnosti můžete, ale velmi specifickým způsobem.

Koncept je pro účely tohoto příspěvku příliš pokročilý, takže se jím nebudeme zabývat, ale pokud budete pokračovat ve své FP cestě, určitě na to narazíte sami.;)

Jaké to má důsledky?

Podešev vnější interakce, kterou může volání funkce mít, je s návratovou hodnotou.

Pokud byste nahradili volání funkce jeho návratovou hodnotou, nikdy by to nezpůsobilo rozdíl ve vašem programu, nazývá se to průhlednost odkazu .

Používání funkcí tímto způsobem výrazně snižuje množství informací, které musí váš mozek načíst, aby porozuměl tomu, co logika dělá, a díky tomu budete z dlouhodobého hlediska produktivnější.

Díky tomu nemusíte mentálně počítat celý aktuální stav vašeho programu v čase X. Stačí se podívat na vstup funkce a budete jisté aktuálního stavu.

Upřímně řečeno, existuje více „pravidel“ pro striktní definici funkce v FP, ale myslím, že je to jediné, které byste zatím měli znát.

Teorie kategorií aplikovaná na programování

Jak jsem řekl, funkcionální programování má své kořeny v matematice, ale konkrétněji v teorii kategorií .

Toto odvětví matematiky se zaměřuje hlavně na "pochopení procesů, které zachovávají matematickou strukturu."

Proč to má něco společného s kódováním? Ukazuje se, že jakákoli datová struktura je také matematickou strukturou. Pro většinu z nás vývojářů naše práce spočívá hlavně v úpravě datové struktury, znovu a znovu.

Porozumění procesům

V podstatě mluvíme o jakékoli transformaci, která se provádí na datech uvnitř datové struktury.

Podívejme se na příklad.

Řekněme, že to uděláme v OOP:

var nbrs = [1,2,3,4,5];
var res = [];

for (let i = 0; i < nbrs.length; i++) {
  if(nbrs[i]%2 == 0){
    res.push(nbrs[i] * 2);
  }
}

console.log(res);
//[4, 8]

Zde je to, co kód dělá podrobně:

  • vytvoření nového pole (stejná struktura jako předchozí pole)

  • pokud je číslo sudé, vynásobíme 2 a přidáme je do nového pole

Pokud nyní analyzujeme tento kód pomocí „procesů“ a „struktury“, o kterých jsme právě mluvili, dojdeme k těmto závěrům:

  • Máme dva procesy:

    1. Odfiltrujeme lichá čísla

    2. Každé číslo vynásobíme dvěma

To je vše, dva procesy, jedna struktura. Velmi dobře se hodí k oboru matematiky, o kterém jsme právě mluvili.

Jak by to tedy vypadalo v FP?

var filterOutOdd = (nbr) => nbr%2 == 0
var multiplyByTwo = (nbr) => nbr * 2

var res = [1,2,3,4,5]
  .filter(filterOutOdd)
  .map(multiplyByTwo)

console.log(res);
//[4, 8]

Postřehy z tohoto příkladu funkčního programování

Upřímně řečeno, v tomto příkladu se nic příliš nemění, ale zkusme z toho získat nějaké postřehy.

Můžete vidět novou funkci použitou přímo na poli, mapu jeden. Tato funkce se obvykle vysvětluje docela triviálně tím, že říká „umožňuje vám použít funkci pro každý prvek seznamu“.

I když to platí pro mapovou implementaci pole, je toho mnohem víc.

Místo toho to řekněme takto:funkce map poskytuje způsob, jak aplikovat funkci na něco zabaleného v určitém kontextu, je ponecháno právě na tomto kontextu, aby byla metoda implementována tak, jak to dává smysl.

Přečtěme si to ještě jednou pozorně:"[mapa] je způsob, jak aplikovat funkci na něco zabaleného v určitém kontextu."

Nyní to přeformulujme podle našeho příkladu:"[mapa] je způsob, jak aplikovat funkci na každou hodnotu zabalenou uvnitř pole."

Můžete vidět, že jsme se vrátili k původní triviální definici, ale nyní rozumíme abstraktnímu konceptu, který je za tím.

Celý smysl zde není jen vědět, jak používat funkci Array.map, ale pochopit, jak je možné, že generická datová struktura, jako je pole, může poskytnout abstraktní obslužnou funkci tak, že funguje s libovolnou data v něm.

Pak a teprve tehdy začnete pociťovat uklidňující světlo funkcionálního programování – před tímto zjištěním se bude FP většinou cítit jako peklo, i když poněkud zábavné peklo (nic jako PHP).

Skládání a opětovné použití

Poslední koncept, který byste měli mít na paměti, abyste nastartovali svou cestu FP, je něco, na co jsme tiše ukazovali od začátku:komposovatelnost.

Vyjádřením manipulace s daty tak podrobně, jak jen dokážete, přirozeně vytvoříte malé logické stavební bloky, které poskytnou mnohem větší složitelnost, než na jakou jste pravděpodobně zvyklí – řekněte to takto:zrnitost vede ke skládání .

Skládání je základem skvělého programování, protože je podmínkou dosažení správné opakovatelné použitelnosti . Jakmile si začnete více a více pohrávat s principy FP, začnete dělat věci znovu a znovu a budete chtít přidat některé „meta“ užitečné funkce, jako je skládání, kari, memorování atd.

Pravděpodobně se vám v tuto chvíli nevyplatí používat, ale rozhodně byste se na ně měli podívat.

Úvahy a závěry

Ukázalo se, že oddělení funkcí, které upravují data, a pořadí, ve kterém je aplikujete, je docela dobrý nápad. Izoluje vaše starosti a snižuje hluk. FP vás přirozeně vede tímto způsobem.

Můžete přemýšlet nebo se dokonce podívat na nějaký kód, který jste již napsali, a zkontrolovat, zda tyto principy sedí. Vsadím se, že to dělají pro většinu kódu, který napíšete. Pouze některé koncepty architektury se v FP modelují mnohem hůře a nemyslím si, že by bylo dobré, abyste se do toho vrhli právě teď.

Jde o to, že celá sféra „obchodní logiky“, kterou obvykle píšete, může snadno těžit z těchto principů bez zásadních změn.

Skok do funkčního paradigmatu

Opravdu dobrá knihovna, se kterou si můžete pohrát, je Ramda.js, pouhé přečtení jejich dokumentace vám poskytne opravdu dobrý přehled.

Zde jsou další odkazy, které vám doporučuji prozkoumat, abyste mohli začít a posunout své znalosti funkčního programování dále:

  • Funkční světlo JS, Kyle Simpson (toto nelze dostatečně doporučit).

  • Převážně adekvátní průvodce funkčním programováním od profesora Frisby

  • Funktory, aplikace a monády v obrázcích

  • Série videí profesora Frisbyho (Úžasný) Egghead o funkčním programování

  • Specifikace Fantasy Land, neboli algebraická specifikace JavaScriptu (tato je dodávána s varováním – zde jsou těžší, abstraktní věci)

Ale co, největší rada, kterou vám mohu dát, je jít na to postupně a klást otázky, pokud se zaseknete.

Nyní jsou zde dvě výzvy, které byste měli zkusit udělat v daném pořadí:

  • Nepište žádné smyčky for na další měsíc

  • Jakmile to uděláte, funkce kódu, jako je filtr, mapa a zmenšení. To bude docela dobrá výzva a donutí vás pochopit, co se děje pod kapotou.

Až to uděláte, rád bych, abyste se sem vrátili a řekli mi, jak experiment probíhá. Opravdu bych ocenil, kdyby se konverzace rozběhla, takže pokud máte nějaké komentáře nebo otázky, klikněte na sekci komentářů níže!

A především šťastné funkční kódování.;)

Pokud se vám tento příspěvek líbil, věnujte prosím chvilku sdílejte to na Twitteru .