Funkcionální programátor

Greenhorn

Re:Funkcionální programátor
« Odpověď #270 kdy: 05. 07. 2015, 14:29:32 »
Jestli Vám mohu skočit do řeči. Když jsem si detailně pročítal tuto diskuzi. Narazil jsem na další způsob IO v čistém jazyce. Mluvil o tom čumil. Reaktivita. Má s ní někdo tady zkušenost? Zkoušel jsem čumilem doporučovaný jazyk Elm, a je to opravdu hodně, hodně zajímavé z mého laického pohledu.
Zatím jsem na Elm koukal jenom zběžně, ale když si přeložím marketingové žvásty do češtiny tak to nevypadá nic moc. Konkrétně třeba "No runtime exceptions". Ten jazyk se vážně chlubí tím, že buď všechno perfektně funguje nebo to naprosto neopravitelně padne na hubu? Na webové appky asi dobrý, no ... ::)
V čistém kódu pokud to chápu správně nemohou být exceptions. Takže Elm to řeší pomocí Maybe a Either. A je to fakt úžasný, když píšu, cítím se jako když píšu funkcionálně, a nemám takový divný pocit jako když píšu něco v Haskellu a plete se mi do toho imperativní IO.

jestli se vám takhle plete IO do kódu v Haskellu, tak něco děláte blbě, já mám v IO monádě u překladače cca 180 řádků (z cca 10k) a to je moc a až se jednou budu hodně nudit, tak to vyčistím na 50 max. (sosnout argumenty a vstupní soubory, vyplivnout binárku)
To nepochybuji že dělám plno věcí špatně, jsem konec konců začátečník. Ale když děláte IDE, musíte mít GUI, a takové i primitivní GUI pomocí gtk2hs je  opravdu na hodně řádků kódu. A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.


Greenhorn

Re:Funkcionální programátor
« Odpověď #271 kdy: 05. 07. 2015, 14:33:24 »
A Task není imperativní, on nedělá žádné vedlejší efekty. Obsahuje pouze informace o tom, co se má udělat [...] A tyto Tasky jsou poté pomocí signálů poslané do výstupních portů běhového prostředí, které už rozkazy vykoná, a případnou reakci zase pošle skrz vstupní porty z kterých je signály zase rozešlou do zbytku programu. Všechno je krásně čisté.
...což je prakticky to samé jako IO monáda ;)
Musím nesouhlasit. Není to jako IO monáda. Neumím to blíže vysvětlit. Musí se to zkusit.

v

Re:Funkcionální programátor
« Odpověď #272 kdy: 05. 07. 2015, 14:35:57 »
A Task není imperativní, on nedělá žádné vedlejší efekty. Obsahuje pouze informace o tom, co se má udělat [...] A tyto Tasky jsou poté pomocí signálů poslané do výstupních portů běhového prostředí, které už rozkazy vykoná, a případnou reakci zase pošle skrz vstupní porty z kterých je signály zase rozešlou do zbytku programu. Všechno je krásně čisté.
...což je prakticky to samé jako IO monáda ;)
Musím nesouhlasit. Není to jako IO monáda. Neumím to blíže vysvětlit. Musí se to zkusit.
asi mám stack overflow nebo něco, o jakém Tasku to mluvíte?

Re:Funkcionální programátor
« Odpověď #273 kdy: 05. 07. 2015, 14:38:21 »
To nepochybuji že dělám plno věcí špatně, jsem konec konců začátečník. Ale když děláte IDE, musíte mít GUI, a takové i primitivní GUI pomocí gtk2hs je  opravdu na hodně řádků kódu. A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.
To je celkem známý problém, že IO je "virální". Záleží na typu řešeného problému, jak moc se to projeví. "v" srovnává nesrovnatelné - překladač je prakticky "batch processing", tam není problém. U interaktivnějších záležitostí, jako je právě to IDE, to problém je. Možná by mohl pomoct ten reaktivní přístup - oddělit věci, které provádí IO a pomocí něčeho na způsob channelů pak posílat do kódu, který už může být čistý. Ale chápu, že se to snadněji řekne, než udělá, jsem si toho vědom, nechci dávat knížečí rady, je to jenom poznámka na okraj, když už tady to reaktivní programování zaznělo...

Musím nesouhlasit. Není to jako IO monáda. Neumím to blíže vysvětlit. Musí se to zkusit.
Vždycky je to de facto variace na nějakou lambdu. Vytvoří se nějaké lambdy a ty se v runtimu spustí, čímž se provede to vlastní IO. Jak přesně je to uděláno je detail, ale vždycky je to něco na tenhle způsob, protože to ani jinak nejde :)

v

Re:Funkcionální programátor
« Odpověď #274 kdy: 05. 07. 2015, 14:46:39 »
Jestli Vám mohu skočit do řeči. Když jsem si detailně pročítal tuto diskuzi. Narazil jsem na další způsob IO v čistém jazyce. Mluvil o tom čumil. Reaktivita. Má s ní někdo tady zkušenost? Zkoušel jsem čumilem doporučovaný jazyk Elm, a je to opravdu hodně, hodně zajímavé z mého laického pohledu.
Zatím jsem na Elm koukal jenom zběžně, ale když si přeložím marketingové žvásty do češtiny tak to nevypadá nic moc. Konkrétně třeba "No runtime exceptions". Ten jazyk se vážně chlubí tím, že buď všechno perfektně funguje nebo to naprosto neopravitelně padne na hubu? Na webové appky asi dobrý, no ... ::)
V čistém kódu pokud to chápu správně nemohou být exceptions. Takže Elm to řeší pomocí Maybe a Either. A je to fakt úžasný, když píšu, cítím se jako když píšu funkcionálně, a nemám takový divný pocit jako když píšu něco v Haskellu a plete se mi do toho imperativní IO.

jestli se vám takhle plete IO do kódu v Haskellu, tak něco děláte blbě, já mám v IO monádě u překladače cca 180 řádků (z cca 10k) a to je moc a až se jednou budu hodně nudit, tak to vyčistím na 50 max. (sosnout argumenty a vstupní soubory, vyplivnout binárku)
To nepochybuji že dělám plno věcí špatně, jsem konec konců začátečník. Ale když děláte IDE, musíte mít GUI, a takové i primitivní GUI pomocí gtk2hs je  opravdu na hodně řádků kódu. A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.
GUI jde asi blbě, uznávám, sám jsem zatím vždycky pokušení zkoušet to v Haskellu odolal (a doufám, že mi to vydrží i do budoucna), myslím, že kvůli takovým věcem vymysleli FRP

interpreter imperativního jazyka je už ale trochu jiný případ, konkrétně měnitelné reference v AST IMHO nejsou potřeba, resp. na co je potřebujete?


Radek Miček

Re:Funkcionální programátor
« Odpověď #275 kdy: 05. 07. 2015, 15:01:07 »
A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.

IO monádu nepotřebujete, můžete si udělat vlastní monádu, která bude podporovat jen omezený počet akcí, a tu pak interpretovat v IO monádě.

V principu podobné, ale jednodušší je udělat handler jako funkci Stav -> (Stav, [Akce]), kde Stav popisuje stav aplikace nebo jeho část a Akce popisuje akci, která se má provést po doběhnutí handleru. GUI pak bude funkce stavu - tj. typu Stav -> GUI - podobně jako to má React.

xyz

Re:Funkcionální programátor
« Odpověď #276 kdy: 05. 07. 2015, 16:49:01 »
Čistota jazyka nezávisí na tom, jak interpretujete výsledky programů.
Možná by se dala použít i takováhle alegorie: představme si, že čistý funkcionální program generuje céčkovský kód, který se poté spustí. To generování je jenom operace nad nějakou strukturou, takže to můžu bez problémů dělat čistě. A v tom céčkovském kódu už zase klíďopíďo můžu mít interakce s vnějším světem, vedlejší efekty, ...

Dalo by se to takhle říct? Já mám za to, že jo.

A v tomto zmysle potom môžeme C vyhlásiť za čistý funkcionálny jazyk. Pravda, pokiaľ ho chápeme spolu s C predprocesorom, ale ten je tam už od dôb Kernighana a Ritchieho.  ;D

http://conal.net/blog/posts/the-c-language-is-purely-functional

Radovan.

Re:Funkcionální programátor
« Odpověď #277 kdy: 05. 07. 2015, 22:26:47 »
Čistota jazyka nezávisí na tom, jak interpretujete výsledky programů.
Možná by se dala použít i takováhle alegorie: představme si, že čistý funkcionální program generuje céčkovský kód, který se poté spustí. To generování je jenom operace nad nějakou strukturou, takže to můžu bez problémů dělat čistě. A v tom céčkovském kódu už zase klíďopíďo můžu mít interakce s vnějším světem, vedlejší efekty, ...

Dalo by se to takhle říct? Já mám za to, že jo.

A v tomto zmysle potom môžeme C vyhlásiť za čistý funkcionálny jazyk. Pravda, pokiaľ ho chápeme spolu s C predprocesorom, ale ten je tam už od dôb Kernighana a Ritchieho.  ;D

http://conal.net/blog/posts/the-c-language-is-purely-functional

No bodejť, vždyť v C je všechno funkce :-D

Inkvizitor

Re:Funkcionální programátor
« Odpověď #278 kdy: 06. 07. 2015, 10:20:38 »
Čistota jazyka nezávisí na tom, jak interpretujete výsledky programů.
Možná by se dala použít i takováhle alegorie: představme si, že čistý funkcionální program generuje céčkovský kód, který se poté spustí. To generování je jenom operace nad nějakou strukturou, takže to můžu bez problémů dělat čistě. A v tom céčkovském kódu už zase klíďopíďo můžu mít interakce s vnějším světem, vedlejší efekty, ...

Dalo by se to takhle říct? Já mám za to, že jo.

Tohle je dost chytrý trollpost. A do značné míry i pravdivý. Rozdíl je v tom, že cpp je hloupý preprocesor a Haskell je úžasně chytrý preprocesor a zatímco ten první neumí vyjádřit velkou část složitého programu samotného tak, aby bylo možno rozumně rozhodnout o jeho korektnosti, u toho druhého to možné je. Druhý rozdíl je v tom, že generovaný jazyk je v tom druhém případě podstatně "hezčí" a kód v něm napsaný verifikovatelnější, ale ten první rozdíl považuji za zásadní.

A v tomto zmysle potom môžeme C vyhlásiť za čistý funkcionálny jazyk. Pravda, pokiaľ ho chápeme spolu s C predprocesorom, ale ten je tam už od dôb Kernighana a Ritchieho.  ;D

http://conal.net/blog/posts/the-c-language-is-purely-functional

Inkvizitor

Re:Funkcionální programátor
« Odpověď #279 kdy: 06. 07. 2015, 10:24:29 »
Čistota jazyka nezávisí na tom, jak interpretujete výsledky programů.
Možná by se dala použít i takováhle alegorie: představme si, že čistý funkcionální program generuje céčkovský kód, který se poté spustí. To generování je jenom operace nad nějakou strukturou, takže to můžu bez problémů dělat čistě. A v tom céčkovském kódu už zase klíďopíďo můžu mít interakce s vnějším světem, vedlejší efekty, ...

Dalo by se to takhle říct? Já mám za to, že jo.

A v tomto zmysle potom môžeme C vyhlásiť za čistý funkcionálny jazyk. Pravda, pokiaľ ho chápeme spolu s C predprocesorom, ale ten je tam už od dôb Kernighana a Ritchieho.  ;D

http://conal.net/blog/posts/the-c-language-is-purely-functional

Omlouvám se za špatně vložený text v předchozí reakci, možno případně smazat, mělo to být takhle:

Tohle je dost chytrý trollpost. A do značné míry i pravdivý. Rozdíl je v tom, že cpp je hloupý preprocesor a Haskell je úžasně chytrý preprocesor a zatímco ten první neumí vyjádřit velkou část složitého programu samotného tak, aby bylo možno rozumně rozhodnout o jeho korektnosti, u toho druhého to možné je. Druhý rozdíl je v tom, že generovaný jazyk je v tom druhém případě podstatně "hezčí" a kód v něm napsaný verifikovatelnější, ale ten první rozdíl považuji za zásadní.

Re:Funkcionální programátor
« Odpověď #280 kdy: 06. 07. 2015, 12:37:18 »
Tohle je dost chytrý trollpost. A do značné míry i pravdivý.
Já bych naopak řekl, že je silně matoucí. Mám-li zdroják v Haskellu a přeložím ho, dostanu zjevně ne-funkcionální strojový kód. "Funkcionálnost" je vlastnost zdrojáku, ne přeloženého programu.

C rozhodně není funkcionální jazyk v žádném smyslu, i kdyby se nakrásně stalo, že zdroják v C a zdroják v Haskellu se přeloží na stejný strojový kód.

Inkvizitor

Re:Funkcionální programátor
« Odpověď #281 kdy: 06. 07. 2015, 12:48:05 »
Tohle je dost chytrý trollpost. A do značné míry i pravdivý.
Já bych naopak řekl, že je silně matoucí. Mám-li zdroják v Haskellu a přeložím ho, dostanu zjevně ne-funkcionální strojový kód. "Funkcionálnost" je vlastnost zdrojáku, ne přeloženého programu.

C rozhodně není funkcionální jazyk v žádném smyslu, i kdyby se nakrásně stalo, že zdroják v C a zdroják v Haskellu se přeloží na stejný strojový kód.

Jenže já se nebavím o C, ale o makrojazyku cpp (preprocesoru). Ten přece produkuje něco podobného jako program v Haskellu s IO monádou, tedy popis (obecně stavového) procesu, který se rozběhne po překladu do binárního kódu, zavedení do paměti a předání řízení operačním systémem. Tak jsem pochopil i ten odkazovaný článek, ten chce ukázat, že vinou IO monády, která do programu v Haskellu zavádí čas a stav a kterou jsme si (alespoň někteří) zde ukázali jako předpis pro interpreter, jak vést výpočetní akci, je funkcionální Haskell v zásadě pouze preprocesorem pro tu "imperativní akci". A zrovna tak i cpp, který je v zásadě čistě funkcionální, připravuje takovou akci vygenerováním výsledného rozvinutého zdrojového programu v C. Je to trochu extrémní a účelová paralela, ale mimo mi nepřijde.

Re:Funkcionální programátor
« Odpověď #282 kdy: 06. 07. 2015, 12:57:05 »
Jenže já se nebavím o C, ale o makrojazyku cpp (preprocesoru).
Aha, sorry, to mi nějak nedocvaklo.

A zrovna tak i cpp, který je v zásadě čistě funkcionální
Není, v cpp žádným program nenapíšeš. Funguje to jenom díky tomu, že tam jsou velké kusy přímo C. Btw, cpp není ani turingovsky kompletní: http://stackoverflow.com/questions/3136686/is-the-c99-preprocessor-turing-complete

Je to prostě zavádějící příklad.

Greenhorn

Re:Funkcionální programátor
« Odpověď #283 kdy: 06. 07. 2015, 14:03:41 »
To nepochybuji že dělám plno věcí špatně, jsem konec konců začátečník. Ale když děláte IDE, musíte mít GUI, a takové i primitivní GUI pomocí gtk2hs je  opravdu na hodně řádků kódu. A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.
To je celkem známý problém, že IO je "virální". Záleží na typu řešeného problému, jak moc se to projeví. "v" srovnává nesrovnatelné - překladač je prakticky "batch processing", tam není problém. U interaktivnějších záležitostí, jako je právě to IDE, to problém je. Možná by mohl pomoct ten reaktivní přístup - oddělit věci, které provádí IO a pomocí něčeho na způsob channelů pak posílat do kódu, který už může být čistý. Ale chápu, že se to snadněji řekne, než udělá, jsem si toho vědom, nechci dávat knížečí rady, je to jenom poznámka na okraj, když už tady to reaktivní programování zaznělo...

Musím nesouhlasit. Není to jako IO monáda. Neumím to blíže vysvětlit. Musí se to zkusit.
Vždycky je to de facto variace na nějakou lambdu. Vytvoří se nějaké lambdy a ty se v runtimu spustí, čímž se provede to vlastní IO. Jak přesně je to uděláno je detail, ale vždycky je to něco na tenhle způsob, protože to ani jinak nejde :)
Souhlasím, vše je variace na lambdu. Ale v reaktivitě tečou data tak jak mají téct v matematické funkci. V případě Haskellu se to tak neděje. A to je ten rozdíl o kterém jsem mluvil.

Greenhorn

Re:Funkcionální programátor
« Odpověď #284 kdy: 06. 07. 2015, 14:08:21 »
Jestli Vám mohu skočit do řeči. Když jsem si detailně pročítal tuto diskuzi. Narazil jsem na další způsob IO v čistém jazyce. Mluvil o tom čumil. Reaktivita. Má s ní někdo tady zkušenost? Zkoušel jsem čumilem doporučovaný jazyk Elm, a je to opravdu hodně, hodně zajímavé z mého laického pohledu.
Zatím jsem na Elm koukal jenom zběžně, ale když si přeložím marketingové žvásty do češtiny tak to nevypadá nic moc. Konkrétně třeba "No runtime exceptions". Ten jazyk se vážně chlubí tím, že buď všechno perfektně funguje nebo to naprosto neopravitelně padne na hubu? Na webové appky asi dobrý, no ... ::)
V čistém kódu pokud to chápu správně nemohou být exceptions. Takže Elm to řeší pomocí Maybe a Either. A je to fakt úžasný, když píšu, cítím se jako když píšu funkcionálně, a nemám takový divný pocit jako když píšu něco v Haskellu a plete se mi do toho imperativní IO.

jestli se vám takhle plete IO do kódu v Haskellu, tak něco děláte blbě, já mám v IO monádě u překladače cca 180 řádků (z cca 10k) a to je moc a až se jednou budu hodně nudit, tak to vyčistím na 50 max. (sosnout argumenty a vstupní soubory, vyplivnout binárku)
To nepochybuji že dělám plno věcí špatně, jsem konec konců začátečník. Ale když děláte IDE, musíte mít GUI, a takové i primitivní GUI pomocí gtk2hs je  opravdu na hodně řádků kódu. A taky potřebujeme měnitelné reference pro komunikaci mezi handlery eventů. Výsledek je ten, že program je povětšinou jen tvořen IO monádou, a vlastně nevidíme rozdíl mezi psaním v C a Haskellu. U interpretru imperativního jazyka je tento problém stejný. Možná ale menší. Parser a serializer lze naštěstí udělat bez IO monády, částečně, měnitelné reference v ast jsou problém, ale samotný evaluátor už nejde udělat bez IO monády.
GUI jde asi blbě, uznávám, sám jsem zatím vždycky pokušení zkoušet to v Haskellu odolal (a doufám, že mi to vydrží i do budoucna), myslím, že kvůli takovým věcem vymysleli FRP

interpreter imperativního jazyka je už ale trochu jiný případ, konkrétně měnitelné reference v AST IMHO nejsou potřeba, resp. na co je potřebujete?
Přímo v AST měnitelné reference nemám. Ale v jmenném prostředí už ano. Takže jsem to řekl špatně, to ale nemění nic na faktu, že tam mám IO velmi mnoho, a vlastně krom parsování a serializování jsem to mohl dělat v C++ a měl bych to rychlejší a tak trošku stejné co se týče podoby kódu. Tou podobou myslím obecné chování kódu.