Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - Mirek Prýmek

Stran: 1 ... 253 254 [255] 256 257 ... 618
3811
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 12. 09. 2015, 14:25:34 »
Pokud je ale ta úloha z definice sekvenční
Ta úloha není z definice sekvenční, [...] dva panáci nesmí současně pracovat s jedním pomerančem.
Jsi si jistý? :))

Nikdo netvrdí, že by to nešlo, samozřejmně že to jde. Ale je to neefektivní, imperativní přístup s mutable objetky dává lepší výsledky.
Citation needed.

3812
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 12. 09. 2015, 09:07:05 »
Však jo, já neříkám nic jiného, takhle to v FP funguje a má fungovat. A FP se taky zaklíná tím, že mávnutím kouzelného proutku řeší problémy s paralelizací a synchronizací, které mají imperativní jazyky. Řeší, ale nikoliv obecně, funguje to jen pro určité úlohy. Ve chvíli, kdy se jedná o nějaký složitejší problém (paralelním výpočtem vznikne více různých scén), tak nemám žádnou metodu, jak je dát deterministicky dohromady
Ale samozřejmě že máš, vždyť jsem ti napsal několik metod. Pokud je ale ta úloha z definice sekvenční, tak ji prostě FP žádným magickým proutkem samo neparalelizuje, to dá rozum. Pokud budeš počítat sha(md5(x)), tak na to prostě nemůžeš jít stylem y=md5(x) z=sha(x) a divit se, že neumíš y a z "dát deterministicky dohromady". Protože to prostě takhle nejde.

Jinak, asi nejlepší přístup, který se dá pro hry použít, je FRP. Viz

Naštěstí vždycky, když něco nejde, tak se najde nějakej blbec, kterej neví, že to nejde, a naprogramuje to :)

3813
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 12. 09. 2015, 01:04:18 »
byla to reakce hlavne na gamera.
Aha, tak to jsme si nerozuměli, já to chápal přesně opačně :)

P.S. nemohli bysme si tykat, mně to vykání vždycky přijde jakoby mi bylo padesát a děsí mě to ;)

Ten rozdil je v implementaci, ale ne semanticky. Hodnota je hodnota - presne jako ve vasem kodu, "zmena" hodnoty proste vytvori novou hodnotu, hotovo.
Já bych to asi polopaticky řekl takhle: celý to nepochopení je způsobený tím, že v imperativních jazycích se pracuje s pamětí - s chlívečky, které jsou nějak pojmenované a postupně do nic něco strkám. Tímpádem i dvě vlákna můžou vidět tentýž chlíveček a něco tam strčit.

U FP se nepracuje s chlívečky, ale s hodnotami. Hodnota je hodnota a nic se do ní nestrká, ani nikdo nemůže změnit 1 na 2 a ještě ke všemu tak, aby pak 1 bylo 2 i v sousedním vlákně. 1 je prostě 1 vždy a všude ;)

3814
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 12. 09. 2015, 00:03:56 »
Řekl bych, že to zmatení s immutable a víc vlákny je z tohoto pohledu:
Mám immutable data, řekněme číslo 5 někde, a mám dvě vlákna, které mají referenci na tu 5 (obě vlákna drží ukazatel na stejnou adresu), pokud obě provedou příčtení čísla 2 , tak dojde k copy on write, obě vlákna ukazují na číslo 7, ale na dvou místech (a pokud původní 5 už nikdo nedrží, likviduje ji GC). Gamer se ptá, jak udělat, aby když ty dvě vlákna to přičtení udělají, aby viděly výsledek 9....
Ano, já si taky myslím, že tak nějak ta gamerova představa je. Jenže tohle se prostě ve FP neděje, to je představa přenesená z imperativních jazyků. Ve FP se nepracuje s žádnými referencemi v tomhle smyslu. Pokud mám dvě funkce f1 a f2, jedna přičítá jedničku a druhá dvojku, a předhodím jím tentýž stav (5), tak mi prostě jedna vrátí 6 a druhá 7, to je správně a má to tak být. Jak jsem říkal, není to nic jiného než starý dobrý https://en.wikipedia.org/wiki/MISD Pokud chci ty funkce na stav aplikovat postupně, tak to opravdu musím udělat postupně - f1 mi vrátí 6 a potom aplikuju f2, která mi vrátí 8. V jazycích, které mají speciální vlastnosti (Haskell) si pak taky můžu hrát třeba s tím, že na pořadí aplikace nezáleží, můžu f1 a f2 snadno sloučit do jedné operace atd. atd. Mám tam úplně jiné možnosti a proto bych jich měl využívat a ne psát kód imperativním stylem a divit se, že mi to nefunguje podle představ...

Mimochodem, když mám immutabilní stav a ten MISD model, tak můžu dělat jednu krásnou věc: spekulativní výpočet. Čili něco, o čem si mutabilní přístup může nechat tak leda zdát :) Opět: je ale potřeba to umět využít a využívat...

...a pokud bych to skutečně chtěl udělat takhle, pomocí nějakého typu reference, tak třeba v Elixiru/Erlangu se na to právě používá actor (agent) - ten drží jedinou kopii dat a provádí nad němi dané operace. Takže obě vlákna drží nějakou referenci na actor (stačí jeho jméno) a posílají mu instrukce, jak má stav měnit. Actor to pak dělá ve vlastním vlákně, klidně asynchronně, původní vlákna dostanou zprávu, až je to hotovo, mezi tím můžou dělat něco jiného klidně.

Prostě možností, jak to celé uspořádat, je bambilion a připadá mi, že gamer se upnul na jednu představu, která ještě ke všemu moc neodpovídá realitě.

(A nebo se možná úplně pletu, gamer přesně ví, o čem mluví, a má pravdu. Pak by to ale chtělo líp vysvětlit pro nás méně chápavé.)


3815
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 22:18:24 »
...a už vůbec nechápu to argumentaci vícevláknovým zpracováním. Když budu mít klasický přístup, řekněme objekt, a budu ho chtít modifikovat ze dvou vláken, tak udělám co? Zamču, upravím, odemču, zamču, upravím. Což můžu úplně klidně dělat i v immutable jazycích, prostě použiju actor.

3816
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 22:13:01 »
Je tahle "1" neco jineho, nez tahle "1"? Jak je odlisim? Hodnota je hodnota a je uplne jedno, jestli ji kopiruju nebo na ni nejak odkazuju.
Neni to jedno, protoze odkaz je prakticky zadarmo, kopirovani muze byt hodne drahy. A jestli nekdo tvrdi, ze problem je v kopirovani, tak to je proste kravina, protoze se nic nekopiruje, jenom odkazuje.

Pokud postava bere pomeranc a oboji ma byt immutable, pak je vysledkem nova postava. Pokud jsou dve ruzne a jsou obe to soucasti jedne immutable sceny, tak je vysledkem jina immutable scena. Je to stejne, jako 1+1+1. Kdybych to mel paralelizovat, tak musim na konci resit synchronizaci, protoze vysledkem je jedna nova zmenena scena, odlisna od puvodni, jina hodnota. Ta synchronizace se postara, ze "vyhraje" jedna z postav, ale nemelo by dojit ke kolizi, protoze nema jak, pokud je to cele immutable.
Sorry, ale já vůbec nechápu, co řešíte. Jaký "Pokud jsou dve ruzne a jsou obe to soucasti jedne immutable sceny"? Mám prostě

Kód: [Vybrat]
def init_state do
  ...
end

def aktualizuj_postavu(postava) do
  ...
end

def aktualizuj_stav(stary_stav) do
  {stara_postava,nejaky_zatracene_velky_data,jiny_zatracene_velky_data} = stary_stav
  nova_postava = aktualizuj_postavu(stara_postava)
  {nova_postava,nejaky_zatracene_velky_data,jiny_zatracene_velky_data}
end

def loop(stav) do
  stav2 = aktualizuj_stav(stav)
  loop(stav2)
end

def main do
  stav1 = init_state
  loop(stav1)
end
- nejaky_zatracene_velky_data se nikam nekopiruji. Jedine, co se zdestruuje a znovu vytvori v kazdem aktualizuj_stav, je jedna trojice ukazatelu. Stejne tak to funguje v aktualizuj_postavu. Nevidim zadny kopirovani velkych dat ani zadny problem se synchronizaci.

Jasne, jsou struktury, kde to dela problemy, protoze jsou moc hluboce vnorene a musi se hodne restaurovat. Ale to jsem prece napsal. Stejne tak muzu chtit paralelni zmeny stavu, ale to se resi partitioningem, to jsem taky napsal.

Fakt nevim, s čím máte pořád problém.

3817
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 20:00:21 »
Já ale neřeším interní implementaci, ta je mi ukradená a může být úplně jiná v každém jazyce. Máš immutable objekt, který nejde změnit. Ty s ním chceš něco udělat, takže musíš vytvořit nový objekt. To je u mě kopie. Říkej si tomu třeba kopírování pointerů, interně to tak klidně může fungovat, ale nesnaž se tvrdit, že jsou to ty stejné objekty. Nejsou. Interně můžou být, ale taky nemusí. Logicky je to jiný objekt.
Tak já nevím, možná mluvím Čínsky, ale vůbec nerozumím, proč tohle píšeš, protože to vůbec nesouvisí s tím, co jsem napsal. No, nechme to být, zavání to spíš zbytečným flejmem než zajímavou diskusí...

Telefonní ústředna je z hlediska logiky funkce jednoduché zařízení, prakticky jen spojuje hovory, dá se to implementovat třeba relativně jednoduchým stavovým automatem, žádné složitosti v tom nehledej.
Ugh. Viděl jsi někdy konfiguraci Asterisku? A viděl jsi někdy specifikaci Jabber protokolu a k tomu alespoň pár rozšíření? :)

Nevím kolik máš zkušeností s vývojem her
To je jednoduchý - žádný. Taky jsem o vývoji her nic netvrdil, mluvím jenom o FP a vyvracím tvoje tvrzení o něm.

3818
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 19:41:35 »
Samozřejmě že jde napsat Wolfenstein 3D v Haskellu. Stejně jako jde napsat webserver v bashi. Fungovat to bude, ale je to spíš jen takové myšlenkové cvičení, prakticky se funkcionální jazyky ve vývoji her neprosazují.
Tak to se neprosazují v ničem, to není specialita her ;) A důvody k tomu můžou být různé - třeba to, že každý programátor začíná imperativně nebo objektově. Kdyby každý začínal funkcionálně, kdoví, jestli by se OOP "prosadilo" ;)

Každopádně se podívej na to video s Carmackem. Když ti Carmack řekne, že funkcionální přístup je fajn, tak asi to s těma hrama nebude tak tragicky nemožný :)

3819
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 19:23:47 »
Tohle je jen slovíčkaření. Když se něco mění, tak se to nově vytvoří. To je u mě kopie. Ty tomu kopie neříkáš, protože se to staré zničí.
Kopie znamená, že mám někde v paměti nějaká data a PŘEKOPÍRUJU je někam do nějaké jiné oblasti paměti - mám dvě KOPIE, které jsou stejné. A k tomuhle právě nikdy nedochází. Pokud jsou někde stejná data, tak se případně kopíruje jenom pointer na ně, protože vím, že je nikdo nikdy nezmění, takže můžu s klidem ten pointer předat komu chci.

(P.S. když mluvím o pointeru, tak mluvím o vnitřní implementaci, v jazyce jako takovém se pointery nepoužívají vůbec, není proč)

Ano, teoreticky to funguje hezky a prakticky to taky funguje hezky, ale jen na úlohy, které pracují s daty, která jsou na sobě málo závislá a vlákna si je navzájem nemění. Taková telefonní ústředna nebo jabber server jsou ideální aplikace pro Erlang, každé vlákno si obsluhuje to svoje a vlákna si navzájem data nemění prakticky vůbec. S Erlangem ale narazíš, když se budeš pokoušet řešit úlohu opačného typu: velké množství vzájemně provázaných a interagujících objektů, žijících v jednom velkém společném světě.
To jsou takové mlhavé statementy, založené kdovínačem. Telefonní ústředna snad není "provázaná"? Každý může komunikovat s každým a když komunikuje A s B, tak ani s jedním nemůže komunikovat nikdo jiný. Jestli tohle není provázanost, tak už fakt nevím :)

Nevím, kolik máš s FP zkušeností, ale mám trochu podezření (bez urážky!) že ty tvoje zkušenosti vychází z toho, že jsi vzal svoje znalosti z konvenčních jazyků, snažil ses to naroubovat na FP a ono to nefungovalo moc dobře. Nevím, v jakém jazyce a co jsi zkoušel napsat, ale takhle obecně se o tom dá mluvit dost těžko, musel by se vzít konkrétní kód a podívat se na něj.

3820
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 19:04:51 »
Zkusím to jednoduše. Mám pomeranč ve scéně. Chci ho přesunout z bodu A do bodu B. Pokud je immutable, musím vytvořit kopii. Buď pomeranče, nebo celé scény.
Neděláš kopii ani jednoho. V "immutable jazycích" to funguje tak, že když se nic nemění, tak se na to nesahá. Když se něco mění, tak se to staré zničí a nové vytvoří. Takže to, co asi chceš říct, není KOPÍROVÁNÍ, ale náklady spojené se zničení a vytvořením nového.

Pokud myslíš tohle, tak to máš částečně pravdu, ale nesmíš si představovat, že ty náklady jsou v takových jazycích stejné jako třeba v Javě. Už jsem to tady psal x-krát v různých tématech: v Erlangu právě proto, že má jenom immutable struktury, má GC jistotu, že pointery jsou jenom "dozadu" (když mám struktury uspořádané podle času vzniku) a nemám tam žádné cykly. Čili můžu struktury rušit velice rychle a dělat různé jiné optimalizace, které bych jinak dělat nemohl. To je příklad jenom jednoho rozdílu, je jich víc. Druhý je ten, co jsem ti psal výš - zahození staré trojice neznamená zahození všech dat, ale jenom té části, která se změnila, ostatní zůstává pořád na místě a nedotčeno. Čili náklady, které s tím jsou spojené, velice záleží na tom, jak ta struktura vypadá. Některé jsou problematické, to je pravda (např. hluboký strom, kde často měním listy, způsobuje, že musím velké části stromu znovu zrekonstruovat).

3821
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 18:50:59 »
tak to je klasická SIMD situace a používá se na to map+reduce.
Sorry, překlep, mělo být "MISD".

3822
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 18:48:03 »
Ta kopie vznikne. Ve chvíli, kdy to paralelizuješ, můžou z jednoho pomeranče vzniknout dva, což nechceš, tohle se v reálném světě neděje.
Nic takového se právě neděje. Smysl immutable dat je v tom, že jsou tím, čím jsou a právěže je NEMUSÍM kopírovat a nikdy nekopíruju - předávám je všude tak, jak jsou, protože vím, že je nikdo nemůže změnit, čili si s tím nelámu hlavu.

Naopak tenhle problém by vznikl u mutable dat - pokud to spustíš na víc jádrech, tak budou dvě různá vlákna přistupovat k tomu stejnému MUTABLE pomeranči, tak máš problém.

3823
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 18:45:06 »
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í.

3824
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 15:18:45 »
s immutable objekty
Pardon, tady jsem myslel spíš "data" než "objekty" ve smyslu OOP.

3825
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 15:17:47 »
Většinu objektů píšu hlavně proto že potřebuji mutable data a udržet data při změnách konzistentní, nepřekvapivě. [...] a měnění pointerů na novou kopii a to přináší zase jiné problémy.
Tohle mi přijde jakože s immutable objekty nemáš moc praktických zkušeností - z jazyků, kde se používají hodně. Protože právě immutable data nemůžou být nekonzistentní z principu, tímhle vůbec není potřeba se zabývat, tenhle problém vůbec neexistuje.

Stejně tak pointery - ty se právě v "ne-mutable" jazycích nepoužívají vůbec, protože k tomu není žádný důvod. Prostě kde mají být data, tam jsou data, a program je jako výrobní linka - něco jde dovnitř, něco jde ven.

Používání pointerů na jedna data na x místech programu je právě to peklo, to největší zlo OOP.

Stran: 1 ... 253 254 [255] 256 257 ... 618