Funkcionální programátor

Radek Miček

Re:Funkcionální programátor
« Odpověď #345 kdy: 07. 07. 2015, 23:31:06 »
Ano, vytvoří se neměnná datová struktura, v které jsou lambdy s vedlejšími efekty. A když se tato struktura poté vyhodnocuje, začnou se vedlejší efekty projevovat.

Vyhodnocení výrazu typu IO a do slabé hlavní normální formy žádné vedlejší efekty neprovede - můžete si ověřit pomocí seq.

Citace
A druhá otázka, pokud je IO monáda čistá, proč ji nemůžeme zparalelizovat pomocí par?

Proč byste nemohl? Můžete klidně napsat putStrLn "a" `par` 3. Samozřejmě, žádný vedlejší efekt se neprovede, protože putStrLn "a"
žádný vedlejší efekt nedělá.


JSH

Re:Funkcionální programátor
« Odpověď #346 kdy: 07. 07. 2015, 23:47:35 »
Ano, vytvoří se neměnná datová struktura, v které jsou lambdy s vedlejšími efekty. A když se tato struktura poté vyhodnocuje, začnou se vedlejší efekty projevovat.

Vyhodnocení výrazu typu IO a do slabé hlavní normální formy žádné vedlejší efekty neprovede - můžete si ověřit pomocí seq.
Mně pro pochopení pomohlo hlavně vykuchání IO a. Ona je to maskovaná funkce World -> (a, World) i když možná je to teď implementované nějak jinak. 'bind' propojí tyhle bloky tak, že svět z jednoho pošle do dalšího. To samé se děje i u State a ST monádů. Veškerý stav, co se tam modifikuje se předává jako parametr a vrací jeho nová verze. Jediný rozdíl mezi IO a všemi ostatními je v tom, že v IO se "předává" stav celého světa.
Spíš než na IO a všechno ostatní si to teď dělím na přiměřené a obludné koule stavu. A některé příklady na FRP v Elmu bych za ty obludné koule stavu teda považoval.
Citace
Citace
A druhá otázka, pokud je IO monáda čistá, proč ji nemůžeme zparalelizovat pomocí par?

Proč byste nemohl? Můžete klidně napsat putStrLn "a" `par` 3. Samozřejmě, žádný vedlejší efekt se neprovede, protože putStrLn "a"
žádný vedlejší efekt nedělá.
Ona se totiž ta funkce World->... začne vyhodnocovat až ta jedna veliká poskládaná lambda vypadne z mainu a runtime do ní strčí ten World. Pak se začnou odbalovat jednotlivé vrstvy. Ale nikde se to nevětví, jen se ty lambdy loupou jak cibule. Nikde tam není nějaký rozumný podstrom který by stálo za to označit a vyhodnotit bokem. Ty rozumné podstromy se objevují až mimo IO kód.

Re:Funkcionální programátor
« Odpověď #347 kdy: 07. 07. 2015, 23:55:25 »
Mně pro pochopení pomohlo hlavně vykuchání IO a.
Mně pomohly tyhle slajdy: http://www.slideshare.net/ScottWlaschin/fp-patterns-buildstufflt - od slajdu 136. Analogie s kolejemi je báječně srozumitelná.

Ona je to maskovaná funkce World -> (a, World) i když možná je to teď implementované nějak jinak.
On se tam ale žádný "world" skutečně nepředává, ne? Měl jsem za to, že to je jenom z důvodu typového odlišení, jakobych udělal třeba a -> [a] a tím dostal nový typ, který mi vynutí to správné poskládání fcí za sebe.

JSH

Re:Funkcionální programátor
« Odpověď #348 kdy: 08. 07. 2015, 00:09:43 »
Mirek Prýmek :
Podle https://wiki.haskell.org/IO_inside je tam fake typ RealWorld, který ale překladač nakonec vyhodí protože odpovídá (). Před časem jsem ho ve zdrojácích i našel, ale teď si nepamatuju přesně kde. Bude někde kolem ST monády, nebo bych aspoň začal hledat od stToIO.

Greenhorn

Re:Funkcionální programátor
« Odpověď #349 kdy: 08. 07. 2015, 00:10:06 »
Pokud je IO monáda čistá, lze udělat následující strukturu kódu
Sorry, ale tomu zápisu nerozumím, nevím, co jsou ty čáry atd. Nešlo by ukázat normální kód, který se v Haskellu nepřeloží?

Neexisuje něco jako runIO protože runIO nelze nahradit svým výstupem.
Tady se už dostávám na tenkej led, takže opět doufám, že to někdo případně opraví: nejde to právě proto, že ty potřebuješ IO vzít a vrátit ho runtimu jako návrat funkce main. V jazyku samotném prostě tu datovou strukturu popisující IO nemůžeš spustit. To je přesně ta moje pointa.

Můžeš tu monádu předávat celým program a vyplivnout ji do main, ale nemůžeš se jí uprostřed programu "zbavit" = "spustit ji" - a to právě proto, že kdyby to bylo možné, pak by Haskell čistý nebyl. Možné to není a Haskell čistý je.

A druhá otázka, pokud je IO monáda čistá, proč ji nemůžeme zparalelizovat pomocí par?  Neměl by to být problém ne? Ale v Haskellu to nejde. Par ignoruje IO monádu.
Tohle už je na mě moc implementačně-specifická otázka, do té se raději pouštět nebudu, nejsem praktický haskeller.
To mne připadá padlé na hlavu. Proti takové argumentaci nemám co říct. Přesně podobné řeči nováčky matou, a zmatou je tak, až radši funkcionální programování zahodí. Vaše argumenty lze po mírné modifikaci nasadit na jakýkoli jazyk, a poté tvrdit že je čistý. Stačí jen vytvořit monády. což není problém.


Greenhorn

Re:Funkcionální programátor
« Odpověď #350 kdy: 08. 07. 2015, 00:13:17 »
Ano, vytvoří se neměnná datová struktura, v které jsou lambdy s vedlejšími efekty. A když se tato struktura poté vyhodnocuje, začnou se vedlejší efekty projevovat.

Vyhodnocení výrazu typu IO a do slabé hlavní normální formy žádné vedlejší efekty neprovede - můžete si ověřit pomocí seq.
Mně pro pochopení pomohlo hlavně vykuchání IO a. Ona je to maskovaná funkce World -> (a, World) i když možná je to teď implementované nějak jinak. 'bind' propojí tyhle bloky tak, že svět z jednoho pošle do dalšího. To samé se děje i u State a ST monádů. Veškerý stav, co se tam modifikuje se předává jako parametr a vrací jeho nová verze. Jediný rozdíl mezi IO a všemi ostatními je v tom, že v IO se "předává" stav celého světa.
Spíš než na IO a všechno ostatní si to teď dělím na přiměřené a obludné koule stavu. A některé příklady na FRP v Elmu bych za ty obludné koule stavu teda považoval.
Citace
Citace
A druhá otázka, pokud je IO monáda čistá, proč ji nemůžeme zparalelizovat pomocí par?

Proč byste nemohl? Můžete klidně napsat putStrLn "a" `par` 3. Samozřejmě, žádný vedlejší efekt se neprovede, protože putStrLn "a"
žádný vedlejší efekt nedělá.
Ona se totiž ta funkce World->... začne vyhodnocovat až ta jedna veliká poskládaná lambda vypadne z mainu a runtime do ní strčí ten World. Pak se začnou odbalovat jednotlivé vrstvy. Ale nikde se to nevětví, jen se ty lambdy loupou jak cibule. Nikde tam není nějaký rozumný podstrom který by stálo za to označit a vyhodnotit bokem. Ty rozumné podstromy se objevují až mimo IO kód.
V Elmu žádná funkce nemá vedlejší efekty a ani nezná měnitelný stav. Vše jsou jenom dráhy signálů, na kterých sedí čisté funkce které je modifikují.

Re:Funkcionální programátor
« Odpověď #351 kdy: 08. 07. 2015, 00:16:34 »
To mne připadá padlé na hlavu. Proti takové argumentaci nemám co říct. Přesně podobné řeči nováčky matou, a zmatou je tak, až radši funkcionální programování zahodí.
Tak teď ti teda vůbec nerozumím. Pouštíš se do silných tvrzení ("Haskell není čistý!") a když se snažím povídavě, ne-rigorozně ukázat, proč čistý je, tak se ti to nelíbí, že to nováčky mate... No tak pokud to nováčky mate, tak nemají vydávat silná prohlášení :) Vždyť pořád si jenom tak neformálně kloužeme po povrchu, nikdo tady ještě nezačal ani podávat nějaké důkazy vlastností funktorů nebo přirozených transformací ;)

Vaše argumenty lze po mírné modifikaci nasadit na jakýkoli jazyk, a poté tvrdit že je čistý. Stačí jen vytvořit monády. což není problém.
Ale vůbec ne. Platí tohle:

pokud je jazyk čistý -> musím IO nějak obchcat, třeba pomocí monád

NEplatí tohle:

pokud má jazyk monády -> je čistý

Čistota je vlastnost jazyka jako celku, s monádami to nemá co dělat, monády jsou jenom nástroj.

Re:Funkcionální programátor
« Odpověď #352 kdy: 08. 07. 2015, 00:16:43 »
Mirek Prýmek :
Podle https://wiki.haskell.org/IO_inside je tam fake typ RealWorld, který ale překladač nakonec vyhodí protože odpovídá (). Před časem jsem ho ve zdrojácích i našel, ale teď si nepamatuju přesně kde. Bude někde kolem ST monády, nebo bych aspoň začal hledat od stToIO.
Jj, to je ono. Nepředává se tam world ve smyslu nějakých dat, ale jenom se záměrně vytváří nový typ.


JSH

Re:Funkcionální programátor
« Odpověď #353 kdy: 08. 07. 2015, 00:18:18 »
V Elmu žádná funkce nemá vedlejší efekty a ani nezná měnitelný stav. Vše jsou jenom dráhy signálů, na kterých sedí čisté funkce které je modifikují.
A ten model v MVC je teda co?

Radek Miček

Re:Funkcionální programátor
« Odpověď #354 kdy: 08. 07. 2015, 00:19:18 »
Vaše argumenty lze po mírné modifikaci nasadit na jakýkoli jazyk, a poté tvrdit že je čistý. Stačí jen vytvořit monády. což není problém.

Na jakýkoliv jazyk to nasadit nejde - musel byste změnit definici toho jazyka.

Například jednoduchý jazyk, na nějž to nejde nasadit, je ML kalkulus - popis sémantiky na straně 395.

Greenhorn

Re:Funkcionální programátor
« Odpověď #355 kdy: 08. 07. 2015, 00:32:45 »
V Elmu žádná funkce nemá vedlejší efekty a ani nezná měnitelný stav. Vše jsou jenom dráhy signálů, na kterých sedí čisté funkce které je modifikují.
A ten model v MVC je teda co?
Neměnný. Na FRP je úžasné že můžeme mít globální stav, který se nemění. Stav je ve FRP uchován ve zpětných signálních vazbách. Neměnní se, pokaždé se vytvoří jeho modifikovaná kopie, a pošle se signálem dál.

Re:Funkcionální programátor
« Odpověď #356 kdy: 08. 07. 2015, 00:34:55 »
Stav je ve FRP uchován ve zpětných signálních vazbách. Neměnní se, pokaždé se vytvoří jeho modifikovaná kopie, a pošle se signálem dál.
Což je přesně tentýž princip jako mají monády, máš to o asi tři příspěvky výš ;) Akorát teda samotné IO žádný stav nepřenáší, ale kdybys chtěl, můžeš si ho tam dát.

Greenhorn

Re:Funkcionální programátor
« Odpověď #357 kdy: 08. 07. 2015, 00:36:48 »
Vaše argumenty lze po mírné modifikaci nasadit na jakýkoli jazyk, a poté tvrdit že je čistý. Stačí jen vytvořit monády. což není problém.

Na jakýkoliv jazyk to nasadit nejde - musel byste změnit definici toho jazyka.

Například jednoduchý jazyk, na nějž to nejde nasadit, je ML kalkulus - popis sémantiky na straně 395.
Ale kdepak. Prostě C je čistě funkcionální, a jakákoli funkce která má vedlejší efekty je ve výsledku jen lambda, kterou interpretuje runtime. Všechno je krásně čisté. Ještě potřebujeme ty monády, aby to mělo všechny náležitosti.

Re:Funkcionální programátor
« Odpověď #358 kdy: 08. 07. 2015, 00:39:32 »
Ale kdepak. Prostě C je čistě funkcionální, a jakákoli funkce která má vedlejší efekty je ve výsledku jen lambda, kterou interpretuje runtime. Všechno je krásně čisté. Ještě potřebujeme ty monády, aby to mělo všechny náležitosti.
C není čistý, protože když dvakrát po sobě zavolám random(), vrátí mi pokaždé jinou hodnotu. V Haskellu nic takového není možné a proto je čistý.

To, že "a <- get" VYPADÁ jako volání funkce, na tom nic nemění, protože to volání fce NENÍ.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #359 kdy: 08. 07. 2015, 00:41:25 »
Neexisuje něco jako runIO protože runIO nelze nahradit svým výstupem.
Můžeš tu monádu předávat celým program a vyplivnout ji do main, ale nemůžeš se jí uprostřed programu "zbavit" = "spustit ji" - a to právě proto, že kdyby to bylo možné, pak by Haskell čistý nebyl. Možné to není a Haskell čistý je.
Tu logiku nechápu. Proč bych se nemohl monády zbavit? Maybe, nebo Either se zbavit lze. Jak vzniká souvislost, že: "kdyby to bylo možné, pak by Haskell čistý nebyl. Možné to není a Haskell čistý je."? Naopak mě přijde, že díky tomu, že IOMonádu nelze substituovat, tak to znamená, že není čistá.