Už po několikáté jsem se nechal nechytat bezelstnou otázkou “Co je vlastně to Rx?”. Kdo už to někdy zkoušel vysvětlit ví, že jakkoli dobře zamýšlená odpověď zní ve výsledku jako pomatené mumlání šíleného vědce na drogách. Je to jev společný doopravdy inovativním technologiím - je obtížné popsat, co vlastně jsou, protože k vysvětlování není možné použít existující základ, resp. podobnost s něčím jiným je tak vzdálená, že je spíš matoucí.
Odkud tedy začít výklad o tom, co je Rx? K tomu je naprosto nezbytné vědět, komu je to vysvětlení určeno, protože to definuje onen počáteční bod přirovnání k něčemu známému. Nejtěžší věc je pak ale vysvětlit, proč má drobný posun od toho známého principu tak zásadní následky.
Je to Stream!
Pro Javisty, kteří už se sžili s Java 8 streamy, je to jednoduché. Rx je něco jako javovské streamy na steroidech. Kromě základních operátorů (metod na objektu stream), které nabízí Java, má Rx nepřeberné množství dalších specializovaných operátorů, které práci se streamem maximálně zefektivní. Nevyhnutelně pak ale přijde námitka, že pro základní práci má Java 8 všechno potřebné a tahat si do projektu další knihovnu jen kvůli nějakým složitým optimalizacím není žádoucí.
Je potřeba vysvětlit, že Rx stream je na rozdíl od Javy defaultně asynchronní, že většinou nevzniká z předem dané kolekce a pak se škála potřebných operátorů velmi rychle rozšíří. To ale narazí na to, že i Java streamy mohou být přepnuty do režimu paralelního zpracování a pointa je právě v tom, že to nevyžaduje žádnou změnu kódu. To je dokonce jedna z nejdůležitějších vlastností Java streamů, protože odemyká potenciál vícejádrových procesorů bez nutnosti explicitního použití synchronizačních primitiv.
Proto je potřeba dále vysvětlit, že účel i modus operandi Java streamů je od Rx zcela odlišný a to jak pro paralelismus, tak z několika dalších pohledů. Tady už ale přirovnání schází a je to ten okamžik, kdy veškeré snahy o vysvětlení připomínají nepříčetné blábolení.
Je to Promise!
Problematiku zpracování asynchronních událostí naopak nemusíte vysvětlovat javascriptařům, kteří už pochopili příslib Promisů (pun intended). Jim můžete celkem jednoduše vysvětlit, že Rx je, zhruba řečeno, knihovna pro řetězení Promisů, čímž se ale dostanete do stejného problému jako s Javou.
Vyrobit ručně sérii několika navazujících promisů je naprosto běžná činnost, proč je na to potřeba nějaká nová knihovna? V tomto případě je hlavní výzva vysvětlit rozdíl mezi použitím pár promisů v jinak normálním kódu a tím, když do promisů nacpeme i všechny jednotlivé kroky byznys logiky, které pak reaktivním způsobem řetězíme do funkčních celků.
Je to Actor!
Principy reaktivního programování zase netřeba vysvětlovat lidem okolo Erlangu, Akky a jiné reaktivní havěti. Je tedy tohle nejlepší výchozí bod pro vysvětlení, co je Rx? Nebo je dokonce Rx jen další knihovna pro výrobu reaktivních backendů pomocí actorů? Není. Ukazuje to třeba skvělý frontendový framework Cycle JS. Tak co to teda sakra je? V tomhle stavu jsem se já sám zastavil na pár měsíců.
Chápal jsem všechny jednotlivé části a koncepty, ale měl jsem neodbytný pocit, že mi něco nedochází, že je nad tím nějaký jednotící princip. Pro všechny ty mapy, flatMapy a foldy bylo jasné, že to má co dočinění s funkcionálním programováním, ale jak to do sebe celé zapadá? Rozsvítilo se mi, až když jsem narazil na článek přímo od autora Rx a v něm na jednoduché konstatování: Observer a Observable (na kterých je Rx založeno) je od začátku designováno jako monáda a komonáda.
Je to programovací jazyk
Až pak mi to celé začalo docházet. Stream událostí je ve skutečnosti chytrý způsob, jak realizovat monadické IO. (stream byl dokonce jeden z IO modelů i u Haskelu, než se definitivně ustálila ona ikonická IO monáda). Každopádně když se k takovému IO doplní pár metod představujících základní jazykové konstrukce, není to nic jiného, než general pupose, pure functional programovací jazyk.
Tuhle myšlenku je potřeba nechat chvilku dozrát, protože jí nejde strávit hned napoprvé: Rx je technicky vzato knihovna, ale efektivně je to programovací jazyk. A ještě jinak: Rx je způsob, jak využít libovolný imperativní jazyk jako hostitele pro pure functional programování. Je to trojský kůň, kterého si nic netušící OOP kodéři sami dovezou za své mocné imperativní hradby. Jasně, Rx nemá třeba currying nebo algebraické datové typy, ale ty hlavní prvky tam jsou - imutabilita, monadické side efekty a hlavně deklarativní algoritmizace včetně lazy evaluation. Jenom to lazy evaluation není Haskelovské pull, tedy vyhodnocení vstupu vždy, když je požadován nový výstup, ale push - vygenerování výstupu pokaždé, když se objeví nový vstup.
Skláním se v hlubokém obdivu před tímto ďábelským plánem, jeho autor musí být génius rozměrů Bondovského zloducha. Proto je naprosto v pořádku se na konci výkladu o Rx zlověstně psychopaticky rozesmát: MUHEHEHEHE. A proto taky většinou skončíte na nejbližší psychiatrické pohotovosti. A upřímně řečeno, když si to po sobě přečtu, ty psychiatry bych asi sám na sebe zavolal taky.
PS PF 2017
Tímto uzavírám první rok svého blogování. Je tu sice jen devět článků, ale myslím, že to je devět dobrých článků. I když jsem začal hlavně kvůli tomu, abych veřejně prezentoval svoje portfolio vědomostí a nemusel už na pracovních pohovorech dělat posrané todo appky, překvapil mě pozitivní účinek zpětné vazby od těch několika málo statečných, kteří se tím šílenstvím prokousali. Každá jedna reakce v diskuzi nebo mailu, nový follower na Twitteru nebo i pouhé přečtení mě naplní nadšením. A za to všem, kteří to dočetli až sem, děkuji. Kéž by byl příští rok alespoň tak dobrý, jako tento.