Ja myslim, ze v jistem smyslu je FP vzdycky "horsi", protoze v jistem smyslu omezuje tvoji svobodu.
Nejde o to, že FP omezuje svobodu, to je v pohodě, pokud omezení něco přinese. Problém je ale v tomto konkrétním případě mnohem hlubší, FP vede k horšímu technickému řešení.
Řeším složitý dynamický svět s velkým množstvím objektů, které vzájemně interagují. Z definice je to jeden svět, který se mění.
Klasický imperativní přístup respektuje tuto definici, když chci spočítat nový stav, tak postupně iteruji přes všechny objekty, spočítám jim nový stav a taky jim ho hned nastavím. Mezi objekty jsou vzájemné závislosti, když spočítám, že panák 1 vleze na políčko A, tak ho tam rovnou umístím. Panák 2, kterého počítám vzápětí, zná aktuální polohu panáka 1 a ví, že na políčko A nemůže, vybere si třeba B. Takový přímočarý přístup má jednu obrovskou výhodu, na konci výpočtu mám vždy celý svět v konzistentním stavu, nikdy se nemůže stát, že jsou dva panáci na políčku A.
Teď na to chci napasovat funkcionální přístup, chci mít konstatní svět a výpočet bez side effectů. Ono to jde, ale musím si uvědomit, co mi to přinese a co mi to vezme. V zásadě to můžu udělat dvěma způsoby.
První je analogií imperativního přístupu, pokaždé když nastavím nový stav objektu, tak vyrobím celý nový "správný" svět. To bude fungovat naprosto stejně jako imperativní přístup. Má to ale svoje ale. I kdyby výroba nového světa nestála žádný výkon navíc (čemuž nevěřím), tak je takový design silně diskutabilní. Mám prakticky netestovatelné funkce, když funkce vrací celý svět, může potenciálně změnit cokoliv. Vůbec nemám přehled o datech, která do funkcí vstupují a které funkce vrací, z interface to není vidět.
Druhý způsob je nedělat změny ve světě ihned, ale schovat si je na později. Vytvořím seznam událostí, co se má se světem stát. Problém tohoto přístupu je v tom, že dává chybné výsledky a nekonzistentní svět. Když počítám všechno z původního světa, můžou se rozhodnout panácí 1 i 2, že oba vstoupí na pole A. Teď co s tím? Nechám panáka 2 tam, kde je, nebo spustím ex-post znovu AI a najdu pro panáka 2 novou pozici? Obě řešení jsou špatná. Hráč očekává, že panák 2 něco udělá a ne že bude občas "zasekávat". Spouštět znovu AI je nekoncepční a stojí to výkon. I když jde o naprosto elemetární příklad, tak stejně nevím, co s tou kolizí udělat. V reálně hře budou tisíce různých událostí a miliony jejich možných vzájemných kombinací. Já nemám dost dobrý mozek na to, abych dokázal domyslet, jak řešit všechny možné kolize. Nevybral bych si toto řešení ani náhodou. Z mého pohledu je nedeterministické.
Pak jsou samozřejmně možné kombinace obou řešení, spočítám události jen pro některé objekty a až potom vytvořím nový svět, nebo můžu svět držet někde bokem a události do něj posílat asynchronně... fantazii se meze nekladou. Ale bohužel to vždycky vede buď na vytváření nového světa nebo k sekvečnímu zpracování událostí.
Nechtěl bych, aby to vyznělo tak, že imperativní přístup je jediný správný a žádné problémy nemá. Samozřejmně že má. Ale pro mě přináší oproti FP dvě zásadní věci, umožňuje mi udržet rozhraní minimalistické (nemusím všude pracovat s celým světem) a umožňuje mi udržet svět v konzistentním stavu.