Funkční programování vysvětleno za 5 minut [With Examples]

Photo of author

By etechblogcz

Tvorba softwaru je komplexní a technicky náročný proces, který vyžaduje pečlivé plánování a strategický přístup k formulaci optimálního řešení daného problému pomocí softwarových nástrojů.

V této souvislosti je klíčovým krokem zvážení vhodného programovacího paradigmatu ještě před zahájením samotného vývoje softwaru.

Programovací paradigma představuje model nebo způsob programování, který definuje specifické rysy, šablony, zásady, pravidla a styly, které určují, jak navrhovat, strukturovat a psát počítačové programy.

Mezi známé programovací paradigmy patří například objektově orientované programování (OOP), procedurální programování, programování řízené událostmi a funkcionální programování.

Funkcionálnímu programování se v poslední době dostává značné pozornosti, neboť se očekává, že povede k vytváření kódu s menším počtem chyb, který je vysoce znovupoužitelný a snadno se udržuje. Co tedy funkcionální programování vlastně je?

Funkcionální programování je podkategorií deklarativního programovacího paradigmatu. Deklarativní programování klade důraz na psaní kódu, který popisuje, čeho má program dosáhnout, a nikoli na to, jak by toho měl program dosáhnout.

Příkladem může být dotazování databází pomocí SQL. Místo explicitního určování způsobu načítání dat se specifikují pouze data, která mají být získána.

Samotné funkcionální programování je přístupem k vytváření počítačových programů prostřednictvím výrazů a čistých funkcí, které se postupně aplikují pro řešení problémů nebo dosažení požadovaných výsledků.

V rámci funkcionálního programování je veškerá funkcionalita programu rozdělena do opakovaně použitelných, čistých funkcí s jasně definovanou odpovědností. Celý program se skládá z těchto čistých funkcí.

Čistá funkce je deterministická funkce, která pro stejné vstupní hodnoty vždy vrací stejný výstup a neovlivňuje žádné jiné části aplikací.

Výsledek čisté funkce tedy závisí výhradně na jejím vstupu, nikoli na globálních proměnných aplikace, které by mohly měnit výsledky funkce.

Tyto čisté funkce přijímají vstup, zpracovávají ho lokálně a vytvářejí výstup, aniž by jakkoli modifikovaly jiné části programu.

Funkcionální programování využívá neměnná data, tedy data, která nelze po vytvoření změnit. Dále se vyhýbá sdíleným stavům, kde by různé části programu mohly přistupovat ke stejným datům a měnit je.

Protože funkcionální programování se silně spoléhá na funkce, jsou tyto funkce považovány za prvotřídní objekty, což znamená, že mohou být předávány jako argumenty, ukládány do proměnných a vraceny z jiných funkcí.

Funkcionální programování navíc preferuje výrazy namísto příkazů, čímž se vyhýbá příkazům ve smyčkách, jako jsou for a while. To má za cíl usnadnit sledování a ladění logiky programu.

Typy funkcionálních programovacích jazyků

Existují dva hlavní typy funkčních programovacích jazyků. Jsou to:

  • Čistě funkční jazyky – Jsou to programovací jazyky, které podporují, prosazují a vyžadují používání funkčních paradigmat, jako je používání čistých funkcí, neměnnost stavů a dat a funkce bez vedlejších účinků na jiné části programu. Příklady čistě funkčních jazyků zahrnují mimo jiné Haskell, Agda, Clean, Idris, Futhark a Elm.
  • Nečisté funkční jazyky – Jsou to jazyky, které sice podporují funkcionální programovací paradigmata, ale zároveň umožňují používání nečistých funkcí, mutací stavu programu a operací s vedlejšími účinky. Mezi příklady nečistých funkčních jazyků patří mimo jiné Javascript, Rust, Erlang, Python, Ruby, Java, Kotlin a Clojure.

Vývojáři používají jak čistě funkční, tak nečisté funkční jazyky. Přechod na čistě funkcionální jazyk však může vyžadovat značné množství času a úsilí, pokud nemáte s funkcionálním programováním předchozí zkušenosti.

Funkční programovací jazyky a knihovny

Mezi populární funkční programovací jazyky a knihovny patří:

#1. Haskell

Haskell je staticky typovaný, lazy, čistě funkcionální programovací jazyk, který je považován za ztělesnění paradigmatu funkcionálního programování.

Kromě odvozování typů nabízí jazyk podporu pro lazy vyhodnocování, kdy se výrazy vyhodnocují pouze v případě, že jsou jejich výsledky skutečně potřeba. Haskell také nabízí podporu pro souběžné programování a jeho kompilátor je vybaven vysoce výkonným garbage collectorem a odlehčenou knihovnou pro souběžnost.

Díky svému důslednému dodržování principů funkcionálního programování může Haskell usnadnit budování komplexních softwarových systémů a zároveň zajistit jejich snadnou údržbu.

V oboru IT se Haskell používá pro vytváření samostatných systémů nebo jazyků specifických pro doménu. Má také široké využití v akademickém prostředí a výzkumu. Mezi společnosti, které používají Haskell, patří mimo jiné Microsoft, Github, Hasura a Lumi.

#2. Ramda

Ramda je funkční programovací knihovna pro jazyk JavaScript. Ramda usnadňuje vytváření komplexní logiky pomocí funkcionální kompozice a poskytuje sadu užitečných funkcí, které podporují používání principů funkcionálního programování v JavaScriptu.

Ramda také poskytuje snadný způsob, jak pracovat s neměnnými objekty a funkcemi bez vedlejších účinků, což jsou klíčové koncepty funkcionálního programování.

Vzhledem k tomu, že JavaScript není čistě funkcionální programovací jazyk jako Haskell, lze pomocí knihovny jako je Ramda využít funkcionální programování a jeho výkonnostních výhod při práci s JavaScriptem.

#3. Elixir

Elixir je univerzální, souběžný, funkcionální programovací jazyk navržený pro škálovatelnost, snadnou údržbu a odolnost proti chybám. Jazyk vytvořil v roce 2011 Jose Valim, běží na virtuálním stroji BEAM a používají ho mimo jiné společnosti jako Heroku, Discord, change.org a Duffel.

Jako funkcionální programovací jazyk podporuje Elixir neměnnost stavů a dat, používání čistých funkcí při psaní kódu a transformaci dat.

Klíčové pojmy ve funkcionálním programování

#1. Čisté funkce

Funkcionální programování široce využívá čisté funkce. Čisté funkce mají dvě hlavní charakteristiky. Za prvé, generují stejný výstup pro stejný vstup bez ohledu na jakékoli vnější faktory, díky čemuž jsou deterministické a tudíž předvídatelné.

Za druhé, čisté funkce nemají vedlejší účinky. To znamená, že nijak nemění vnější prostředí mimo svůj rozsah.

Některé příklady čistých funkcí:

//funkce pro výpočet druhé mocniny čísla
function square(x) {
    return x * x;
}

//funkce pro sečtení dvou proměnných
function add(a, b) {
    return a + b
}

Výše uvedené funkce vracejí stejný výstup pro stejné vstupy a nemají žádné vedlejší účinky mimo jejich rozsah.

#2. Neměnnost

Ve funkcionálním programování jsou data neměnná. To znamená, že jakmile byly proměnné inicializovány, nelze je modifikovat. Tím je zajištěno zachování stavu proměnné v průběhu celého programu.

V případě, že chcete provést jakoukoli úpravu proměnné nebo s ní provést operaci, můžete vytvořit novou proměnnou pro uložení aktualizovaných dat beze změny původní proměnné.

#3. Funkce vyššího řádu

Funkce vyššího řádu jsou funkce, které přijímají jednu nebo více funkcí jako argumenty a/nebo vracejí funkci.

Funkce vyššího řádu jsou užitečné ve funkcionálním programování, protože umožňují kombinovat více funkcí za účelem vytvoření nových funkcí, umožňují použití zpětných volání, umožňují abstrakci běžných vzorů do opakovaně použitelných funkcí a v neposlední řadě umožňují psát stručnější a expresivní kód.

Příklad funkce vyššího řádu je uveden níže:

// Funkce vyššího řádu, která vrací funkci, jež vynásobí
// číslo daným faktorem
function multiplier(factor) {
    return function (number) {
      return number * factor;
    }
  }
  
const double = multiplier(2); 
const triple = multiplier(3);
const quadruple = multiplier(4);
  
console.log(double(5)); // Výstup: 10
console.log(triple(5)); // Výstup: 15
console.log(quadruple(5)); // Výstup: 20

#4. Rekurze

Protože funkcionální programování spoléhá na výrazy namísto příkazů, příkazům toku řízení, jako jsou smyčky for a while, se v tomto paradigmatu vyhýbáme. Tyto příkazy smyčky jsou nahrazeny pomocí rekurze, která se používá k provádění iterací ve funkcionálním programování.

Rekurze zahrnuje funkci, která se opakovaně volá, dokud není splněna podmínka ukončení. Pomocí rekurze je složitý problém rozložen na menší, jednodušší podproblémy, které se pak rekurzivně řeší, dokud není dosaženo základního případu, který poskytuje řešení většího komplexního problému.

#5. Deklarativní programování

Funkcionální programování je podparadigma v širším deklarativním programovacím paradigmatu, které zahrnuje programovací paradigmata, která se zaměřují na psaní kódu z hlediska toho, čeho je třeba dosáhnout, místo explicitního uvádění, jak toho dosáhnout.

V tomto ohledu by při použití funkcionálního programovacího paradigmatu měl váš kód popisovat, čeho má být dosaženo nebo jaký problém se má vyřešit.

Způsob dosažení výsledku je v kompetenci programovacího jazyka, který používáte. To pomáhá při psaní stručnějšího a snadno čitelného kódu.

#6. Bezstavovost

Funkcionální programování klade důraz na bezstavový kód, kde kód neudržuje globální stav, který by mohl být funkcemi modifikován. Výsledky funkcí závisejí výhradně na předaných vstupech a nemohou být ovlivněny závislostmi na jiných částech kódu.

Použité funkce nemohou měnit stav nebo proměnnou v programu, která je mimo jejich rozsah.

#7. Paralelní provádění

Protože funkcionální programování využívá neměnné stavy, používá čisté funkce a neměnná data, umožňuje paralelní provádění více výpočtů současně.

Vzhledem k tomu, že každá funkce se musí vypořádat pouze s daným vstupem bez obav z vedlejších účinků z jiných částí programu, lze komplexní problémy rozdělit na menší dílčí problémy a provádět je paralelně, což vede k lepšímu výkonu a efektivitě.

Výhody funkcionálního programování

Mezi výhody funkcionálního programování patří:

Méně softwarových chyb

Kromě toho, že je kód implementující paradigma funkcionálního programování čitelnější a srozumitelnější díky používání čistých funkcí, umožňuje funkcionální programování psát kód s menším počtem chyb.

Protože funkcionální programování pracuje s neměnnými stavy, nemůže docházet k tomu, že by několik částí programu měnilo stav proměnné nebo celého programu. To vede k menšímu počtu chyb, které by mohly vzniknout při úpravách dat z více míst kvůli sdíleným stavům.

Zlepšuje čitelnost kódu

Funkcionální programování je podparadigma deklarativního paradigmatu, které klade důraz na psaní kódu, který popisuje, co je třeba udělat, spíše než jak to udělat. To ve spojení s používáním čistých funkcí vede ke kódu, který je srozumitelný, snadněji čitelný a pochopitelný a snadno se udržuje.

Zlepšuje znovupoužitelnost kódu

Implementace funkcionálního programování vyžaduje rozdělení složitých problémů na menší dílčí problémy a řešení těchto problémů pomocí čistých funkcí. Tyto funkce lze snadno skládat a znovu použít k řešení dalších složitých problémů. Díky používání čistých funkcí a neměnných stavů umožňuje funkcionální programování psát vysoce znovupoužitelný kód.

Snazší testování a ladění

Funkcionální programování používá čisté funkce, které nemají vedlejší účinky, závisejí pouze na svých vstupech a pro stejnou sadu vstupů generují konzistentní deterministické výstupy.

Díky tomu je funkcionální programování ze své podstaty snadné testovat a ladit, protože není třeba sledovat proměnné a to, jak se mění v různých částech programu.

Vzhledem k tomu, že ve funkcionálním programování neexistují žádné závislosti, je ladění a testování jednodušší, protože se můžete zaměřit na konkrétní části programu.

Podporuje souběžnost a paralelismus

Protože funkcionální programování podporuje bezstavovost a neměnnost dat, umožňuje bezpečné provádění více čistých funkcí paralelně nebo souběžně. Schopnost spouštět více operací paralelně vede k vyšší rychlosti zpracování a lepšímu využití vícejádrových procesorů.

Jako programovací paradigma může funkcionální programování pomoci při psaní čitelnějšího a snáze srozumitelného kódu s menším počtem chyb a vynikající podporou paralelismu, umožňujícího efektivní využití vícejádrových procesorů. Funkcionální programování umožňuje budování softwarových systémů, které jsou spolehlivější a snadno se škálují.

Omezení funkcionálního programování

I když má funkcionální programování mnoho výhod, přináší s sebou i náročnější učební křivku, která vyžaduje, aby vývojáři investovali spoustu času a úsilí do osvojení si tohoto paradigmatu. Je to dáno tím, že zavádí nové způsoby strukturování kódu a nové koncepty programování.

Kódování pomocí funkcionálního programování může být extrémně složité a obtížné, protože nevyužívá intuitivnější konstrukce, jako jsou smyčky for a while. Psaní programů rekurzivně není snadné.

V důsledku toho mohou vývojáři potřebovat více času na osvojení si funkcionálního programování, zejména pokud přicházejí z jazyků, které používají proměnlivé stavy, jako je například objektově orientované programování.

Další omezení funkcionálního programování vyplývá z jeho základního principu neměnnosti. Vzhledem k tomu, že data a stavy jsou neměnné a místo modifikace stávajících struktur jsou vytvářeny nové datové struktury, výsledkem je funkcionální programování, které využívá více úložného prostoru. Neměnná povaha funkcionálního programování může také vést ke zhoršení výkonu aplikací.

Závěr

Přestože funkcionální programování existuje již dlouho, v poslední době se stává stále populárnějším paradigmatem. I když to může být poněkud obtížné pochopit, vývojáři mohou mít velký užitek z toho, že se s tímto paradigmatem seznámí a naučí se různé způsoby, jak mohou implementovat funkcionální programování při psaní programů.

Protože není nutné používat čistě funkcionální programovací jazyky, jako je Haskell, lze koncepty funkcionálního programování implementovat v jazycích, jako jsou Javascript, Java, Python a Kotlin, a využívat výhod funkcionálního programování ve svých projektech.

Můžete také prozkoumat některé zdroje, jak se naučit Python pro začátečníky.