Tusim autor hry Iconclad :Steam Legions (psano v Clojure) se v blogu tvaril, jak se mu s immutable stavem hry strasne dobre pracovalo.
Pokud někoho immutables ve hrách zajímá, mohlo by ho zajímat i tohle:
https://www.youtube.com/watch?v=yIlDBPiMb0o (webová hra, jednoduchá, ale na videu celá vysvětlená)
Immutable objekty fungují hezky v teorii, ale prakticky narazíš na to, že stejně musíš řešit synchronizaci. Dělám třeba hru, kde panáci sbírají pomeranče. Panák přijde k pomerančí ležícímu na zemi a strčí si ho do kapsy. Pomeranč je immutable. Takže co panák udělá, vytvoři novou kopii pomeranče, která je v jeho kapse. Starý pomeranč zruší. Doteď všechno v pohodě.
No jo, jenže to asi mluvíš o nějakém jazyku, který má immutabilitu jenom na okrasu, nebo nevím. Protože vůbec nevím, proč by se něco někam mělo kopírovat, minimálně pokud scéna i panáček běží v jednom procesu.
Např. v Elixiru/Erlangu pokud mám trojici definující stav světa {panacci,prostredi,nastaveni} a chci zmenit jenom panacky, takze vytvorim novou trojici {panacci2,prostredi,nastaveni}, tak se s prostredi a nastaveni nedela vubec nic, interne se vezmou dva pointery a jenom ty se prekopiruji do nove trojice. A prekopirovani pointeru nebo zmena property snad neni rozdíl, nad kterým by bylo potřeba nějak zvlášť dumat. Čili žádné "starý pomeranč zruší", ale "pointer na pomeranč se smaže z prostředí a vloží panáčkovi do kapsy".
A teď si řeknu, no jo, když mám všechno immutable a mám spoustu jader CPU, tak pustím všechny panáky paralelně a všechno bude mnohem rychlejší. Jenomže pak přijdou k jednomu pomeranči paralelně dva různí panáci. Oba ve stejný čas vytvoří kopii pomeranče ležícího na zemi a strčí si ho do kapsy. Starý pomeranč zruší. Všechno krásně funguje, akorát místo jednoho pomeranče mám dva. To není úplně přesně to, co bych chtěl.
S celou immutable scénou si to už vůbec nedovedu představit. Mám scénu na které je 50 panáků. Každý panák něco udělá a vytvoří si kopii scény. Mám 50 různých scén, každá je jiná. Co s tím budu dělat, jak dám 50 různých scén nějak deterministicky dohromady do jedné?
Opět - to mluvíš asi o nějakém jazyku, který obsahuje sdílená data. Tímpádem potřebuješ synchoronizaci. Tímpádem můžeš úplně s klidem zůstat u klasického OOP, seš tam, kdes byl.
Znovu pro příklad: v Erlangu bys měl třeba prostředí a každého z panáčků jako samostatný proces a ty procesy by si posílaly zprávy. Nebo bys mohl mít jako samostatný proces každé políčko herního plánu a tímpádem by mohlo docházet i k paralelním změnám v různých místech plánu.
Zkušenosti mám, například když spustíš dvě vlákna a každému předáš immutable kopii tvých dat, tak po skončení vláken musíš psát extra algoritmus na sloučení výsledků. U klasické synchronizované mutable struktury tohle neřešíš.
Samozřejmě má immutable přístup svoje výhody, ale není to univerzální všelék, jsou případy kdy je to kontraproduktivní.
Tohle je stejnej případ, jako jsem teď psal kolegovi - tohle se v jazycích, které OPRAVDU immutable používají (tj. nemají ho jenom na okrasu) prostě neděje. Pokud máš jedna data a nad nimi chceš spustit deset různých operací, tak to je klasická SIMD situace a používá se na to map+reduce.
Spouštět x modifikací téže struktury (např. toho herního plánu) je nesmysl. Pokud vím, že to budu chtít dělat, tak strukturu rozparceluju a události na jedné parcele se implicitně serializují.