Reaktivní programování

Reaktivní programování je paradigma programování orientované kolem datových toků a šíření změn. To znamená, že by mělo být možné vyjádřit statické nebo dynamické datové toky v programovacích jazycích jednoduše a že základní provedení modelu bude automaticky kopírovat změny prostřednictvím datového toku.

Například v imperativním programování by nastavení  znamenalo to, že je přiřazen výsledek v okamžiku, kdy je výraz vyhodnocen a později lze hodnoty a  změnit bez vlivu na hodnotu . Nicméně v reaktivní programování se hodnota automaticky aktualizuje vždy, když se změní hodnoty  a , bez příkazu znovu vykonávajícího parametr .

Reaktivní programování bylo především navrženo jako způsob, jak zjednodušit tvorbu interaktivních uživatelských rozhraní, animací v reálném čase, ale je v podstatě obecné paradigma programování.

Pro příklad v model–view–controller architektuře může reaktivní programování povolit změny v základním modelu, ty se automaticky projeví v modelu zobrazení, a naopak.[1]

Definice Reaktivního Programování

Je vhodné rozlišit zhruba tři druhy počítačových programů. Transformační programy vypočítají výsledky z daných vstupů souboru; typickým příkladem jsou kompilátory, nebo numerické výpočetní programy. Interaktivní programy pracují svou vlastní rychlostí s uživateli nebo s dalšími programy, z uživatelského hlediska je time-sharing systém interaktivní. Reaktivní programy také udržují neustálé interakce se svým prostředím, ale při rychlosti, která je určena prostředím, nikoliv samotný program. Interaktivní programy pracují svým vlastním tempem a hlavně jednají s komunikačními prostředky, zatímco reaktivní programy fungují pouze v reakci na vnější požadavky a většinou reagují na přesné obsluhy přerušení. Real-time programy jsou obvykle reaktivní. Nicméně zde jsou reaktivní programy, které nejsou obvykle považovány za programy v reálném čase, jako jsou protokoly, systémové ovladače, nebo rozhraní manipulátory člověk–stroj.

—Gérard Berry[2]

Přístupy k vytváření reaktivních programovacích jazyků

Existuje několik populárních přístupů k vytvoření reaktivních programovacích jazyků. Některé jsou specializované jazyky, které jsou specifické pro některé domény (jako je real-time nebo embedded computing). Některé jsou univerzálními jazyky, které podporují reaktivitu. A konečně některé jsou knihovny nebo vestavěné doménově specifické jazyky, které umožňují reaktivitu spolu s nebo nad rámec stávajících univerzálních programovacích jazyků.

Programování modelů a sémantika

Řadu modelů a sémantik upravuje rodina reaktivního programování. Můžeme je volně dělit podle následujících rozdílů:

  • Synchronizace: je základní model času synchronní nebo asynchronní?
  • Determinismus: deterministické vs. nedeterministické v obou hodnocení procesu a výsledků
  • Proces aktualizace: zpětná volání vs. tok dat vs. účastníci

Implementační techniky a výzvy

Podstatou Implementace

Runtime reaktivní programovací jazyky obvykle spoléhají na graf, který zachycuje závislosti mezi reaktivními hodnotami. V grafu, uzly představují výpočty a hrany modelu závislost (vztahy). Jazyk runtime používá graf aby sledoval výpočty, které musí být provedeny znovu, když je jeden ze vstupů změněn.

Změna šíření algoritmy

Zde je několik technik, které reaktivní programovací systémy využívají. Ty představují tok dat grafem explicitně. Nejčastější algoritmy jsou:

  • pull
  • push
  • hybridní push-pull

Co je push?

Na úrovni provedení v reakci na událost se skládá z množin napříč grafem informace, že se stala změna. Důsledkem je, že výpočty, které jsou ovlivněny změnou a mohou být zastaralé, jsou označeny jako re-executed. Tyto výpočty jsou obvykle v tranzitivním uzavření změněného zdroje. Změna šíření může vést k aktualizaci na grafu.

Implementační výzvy v reaktivním programování

Závady

U množení změn je možné vybrat šíření změny tak, že hodnota výrazu není přirozeným důsledkem zdroje programu. Ukážeme si to snadno s příkladem. Předpokládáme, že sekundy je reaktivní hodnota, která se mění každou vteřinu a reprezentuje aktuální čas (v sekundách). Zvažte tento výraz:

t = sekundy + 1
g = (t > sekundy)

Protože t by měla být vždy větší než sekundy, tento výraz by měl vždy vyhodnotit na hodnotu true. Bohužel, to může záležet na pořadí vyhodnocení. Když sekundy změníme, dva výrazy se poté mají aktualizovat: sekundy + 1 a podmínka. Pokud první hodnotí před druhou, pak se tato invarianta bude držet. Pokud však podmíněné aktualizace budou jako první, s použitím staré hodnoty t a novou hodnotou sekundy, pak výraz se vyhodnotí na hodnotu false. Tomuto říkáme tzv. glitch.

Některé reaktivní jazyky jsou glitch-free, a mají tuto vlastnost. Toto je obvykle dosaženo tím, že topologicky třídí výrazy a aktualizují hodnoty v topologické pořadí. To může mít vliv na výkon, jako je zpoždění dodávky hodnot (vzhledem k pořadí, propagace). V některých případech proto reaktivní jazyky povolují závady a vývojáři musí být vědomi možnosti, že hodnoty mohou dočasně selhat, aby odpovídaly programovému zdroji a že některé výrazy se mohou vyhodnotit vícekrát (například t > sekund může hodnotit dvakrát: jednou, když nová hodnota sekundy dorazí a ještě jednou, když je t  aktualizováno).

Cyklické závislosti

Topologické třídění závislostí závisí na grafu závislosti je zaměřena acyklický graf (DAG). V praxi, program může definovat závislosti grafu, který má cykly. Obvykle reaktivní programovací jazyky očekávají že tyto cykly mají být „ukončeny“ tím, že některé prvky podél „zpětné hrany“ na povolení reaktivní aktualizaci ukončí. Typicky jazyky poskytnou prostředek, jako je delay, který je používá mechanismus aktualizace pro tento účel, protože delay znamená, že to co následuje, musí být hodnoceno v „příštím kroku“ (umožňuje současné hodnocení ukončit).

Dynamická aktualizace grafu závislostí

U některých reaktivní jazyků graf závislosti je statický, tj. graf je stanoven v průběhu provádění programu. V jiných jazycích graf může být dynamický, tj. že se může změnit, jak se program spustí. Pro jednoduchý příklad, zvažte tento ilustrativní příklad (kde sekundy je reaktivní hodnota):

t =
 if ((sekundy mod 2) == 0):
 sekundy + 1
else:
 sekundy - 1
end
t + 1

Každou sekundu, se hodnota tohoto výrazu změní na různé reaktivní výrazy, na kterých t + 1 závisí. Proto graf závislosti aktualizuje každou sekundu.

Reference

V tomto článku byl použit překlad textu z článku Reactive programming na anglické Wikipedii.

  1. TRELLIS. Model-view-controller and the observer pattern. [s.l.]: Tele community Dostupné v archivu pořízeném z originálu dne 2016-03-03. (anglicky) .
  2. http://www-sop.inria.fr/members/Gerard.Berry/Papers/Berry-IFIP-89.pdf

Související články

  • Service Component Architecture
  • Meteor (web framework)
  • QML
  • Elm (programovací jazyk) Reaktivní složení webové uživatelské rozhraní.
  • knihovna JavaScript, napsaná Facebookem pro vytváření uživatelských rozhraní