Tady jsme si spíš nerozuměli, předpokládal jsem, že se porovnává funkce z imperativních jazyků (tj. v podstatě procedura) s objektovým posíláním. Funkcionální funkci (tj. v podstatě matematickou funkci) jsem na mysli neměl.
Ok.
To vypadá dobře. I když implementovat asynchronní v synchronním jde tady.
Jde, ale je to míň praktické - musím pro každé volání rezervovat thread/process. Proto je defaultní asynchronnost lepší, protože asynchronní je prostě asynchronní a pokud chci blokovat, tak blokuju přímo ve vlákně volajícího, něpotřebuju nic "navíc".
3. odeslání zprávy nemusí nic "vracet" nebo může "vracet" víc hodnot postupně
...
To už je věcí implementace na druhé straně, to bych tu nerozebíral. Ale vypadá to zajímavě.
Chtěl jsem tím říct, že (asynchronní) posílání zpráv je "obecnější" než volání funkce - v takovém spíš sémantickém než technickém smyslu, protože samozřejmě funkci taky můžu předat callback, který pak bude volat znovu a znovu...
Monády mi stačila, jen jsem je nestihl prostudovat.
Monády jsou v principu celkem jednoduché, ale bývá problém je vysvětlit/pochopit, proto jsem dal příklad, který je myslím každému programátorovi jasný na první pohled.
Každopádně důsledkem je, že vnitřně je modul sice immutable, ale navenek (a to mě v interakci s ostatními zajímá) pochopitelně mutable.
Tady nebezpečně motáš pojmy. Mutabilita se týká
dat. Co je "mutabilita modulu", to bysme si museli nějak zadefinovat, jinak to bude plácání o koze a o voze
Tzn. tvrzení, že v FP je vše immutable, asi nebude pravdivé. Dále předpokládám, že jsou hodnoty při volání funkce či posílání zprávy předávány odkazem, jinak by celé toto čarování nemělo smysl.
V různých jazycích je to různě. V tom Elixiru, ve kterém příklad byl, platí, že jakmile mám jednou nějaká data, tak je už nikdy nemůžu změnit. Čili tam vůbec nedává smysl mluvit o volání odkazem nebo hodnotou - je to úplně to samé, je mi úplně jedno, jak je to implementované, protože třeba asoc. pole {'a' => 1} bude už navždy mít jenom jeden klíč, nikdo tam nijak nemůže přidat druhý. Čili to pole můžu úplně klidně předávat kamkoli, do kolika vláken chci a nemusím se bát, že by mi ho nějaké jiné vlákno neočekávaně změnilo pod rukama. Pokud někdo chce do pole přidat další klíč, vznikne mu
nové pole, které s tím starým nemá nic společného (a navíc protože původní už nikdo nemůže změnit, můžou ty dvě pole úplně klidně a bezpečně sdílet data - ale to už je otázka implementace, která mě jako uživatele jazyka nezajímá).
Nicméně Elixir (a jeho "podvozek" Erlang) negarantují to, že když dvakrát zavolám tu stejnou funkci se stejnými parametry, dostanu stajný výsledek. Čili k tomu stavu můžu přistupovat přes funkci (která obalí posílání zpráv) a dostanu pokaždé stav, který je aktuální v daném okamžiku.
Ve víc striktních jazycích (Haskell, Elm, ...) tohle neplatí. Tam ta garance je ještě tvrdší než v Elixiru. Proto jsem říkal, že v různých je zycích je "míra imutability" (a tím i míra platných garancí) různá.