Funkcionální programátor

v

Re:Funkcionální programátor
« Odpověď #150 kdy: 01. 07. 2015, 21:05:27 »
pure funkcional

jak to definujete? :)


BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #151 kdy: 01. 07. 2015, 21:21:58 »
pure funkcional

jak to definujete? :)

Na čumilově definici se neshodneme?

1) FP je paradigma, které je inspirované matematickou teorií funkcí a celkově podobou a chováním matematických výrazů. Jak se chovají matematické funkce ? Nemají žádný vnitřní stav, jediný vstup mají skrz své argumenty a jediný jejich výstup je hodnota kořenového výrazu funkce. Matematická funkce se stejnými argumenty vrátí vždy stejný výsledek. Je jedno kolikrát ji vyhodnotíme a nebo kdy ji vyhodnotíme. Matematická funkce je absolutně deterministická. Jak dosáhnout těchto parametrů v programovacím jazice ? Napřed musíme všechna data zmrazit, žádný objekt nesmí být po vytvoření měnitelný, v matematice také nezměníme již jednou přiřazenou hodnotu argumentu. Tím dosáhneme, že nemůžeme pomocí datové mutace výsledek funkce poslat skrz vstupní argumenty. Jako další krok musíme zajistit, aby funkce za žádnou cenu neměnila globální stav světa či běhového prostředí. Žádná matematická funkce něco takového neumí. Ale kdyby uměla, bylo by to fakt ale fakt drsný, jen si to představte, napíšete matematickou funkce, a postupně jak ji řešíte tak se třeba postaví dům (a nebo třeba smahnete někoho bleskem). Cool, vysvětlil sem magii. Ale tak to v našem vesmíru nefunguje. Teď zase vážně. Funkce, které splňují podmínky matematické funkce se nazývají čisté funkce, a jazyk je FP (dnes pure FP ...) pouze za předpokladu že všechny jeho funkce jsou čisté funkce.

Plus případně explicitně vyjádření o referenční transparentnosti (to kdyby někdo přišel s nějakou haluzí, i když mě to z té definice vyplývá).

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #152 kdy: 01. 07. 2015, 21:24:27 »
No, a ještě jsem tam měl zvýraznit to s těma side efektama.

Radek Miček

Re:Funkcionální programátor
« Odpověď #153 kdy: 01. 07. 2015, 21:25:40 »
Zatímco když do jazyka s Uniqueness typing naimplementuješ něco jako forkWorld, tak jsi taky dosáhl svého, taky použil hrubou sílu, ale už to nebude Uniqueness typing, protože jsi porušil pravidlo ohledně jediné instance.

Když bychom vzali nějakou konkrétní formulaci UT (například z dizertace Dana Harringtona A type system for destructive updates in declarative programming languages), tak tam nejspíš žádné pravidlo ohledně jediné instance nebude. Budou tam jen pravidla, která říkají, že za určitých předpokladů lze přiřadit výrazům určitý typ. Naopak tam nebudou pravidla, která by říkala, že určitým výrazům nejde přiřadit určitý typ. Když tam tedy přidám axiom, že výraz forkWorld má určitý typ, tak se nemohu dostat do sporu se stávajícími pravidly - ze stávajících pravidel nejde odvodit negace přidaného axiomu.

Tvrzení "In computing, a unique type guarantees that an object is used in a single-threaded way, with at most a single reference to it." slouží jako motivace pro pravidla v UT.

Citace
A bude to potom ještě Uniqueness typing?

Myslím, že by se tomu říkalo UT, i kdyby tam přibyla funkce coerce, která provede libovolné přetypování (pomocí ní můžete napsat i forkWorld).
Viz třeba dokumentace jazyka Idris.

Citace
Jako ve výsledku vlastně jde jen o to, že když něco nazveš nějak, tak od toho taky něco očekáváš. A když od jazyka, který o sobě tvrdí, že je pure funkcional, a on pak ve skutečnosti není, tak to naštve. Když by se řeklo, že Haskell je "pure funkcional s výhradou", tak by byl třeba čumil spokojenej.

Ale Safe Haskell s IO monádou bez věcí jako unsafePerformIO, unsafeCoerce atd., je čistě funkcionální - definici splňuje bez výhrad (všechny výrazy tam jsou referenčně transparentní). Rovněž tam funguje substituční model, když zkoumáte chování programů.

Radek Miček

Re:Funkcionální programátor
« Odpověď #154 kdy: 01. 07. 2015, 21:28:41 »
Na čumilově definici se neshodneme?

Ta v Haskellu platí i s IO monádou.


v

Re:Funkcionální programátor
« Odpověď #155 kdy: 01. 07. 2015, 21:39:41 »
tak já po příspěvku RM už jenom doplním, že z toho obrovského čumilova příspěvku je zřejmé, že nepochopil jak monáda funguje (to o měnitelných referencích) a proto asi to nedorozumění

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #156 kdy: 01. 07. 2015, 22:01:58 »
Mě tam zase zaujalo to vztekání se ohledně Race Condition. Je fakt, že když je něco funkcionální podle té čumilově definice, tak k souběhu nesmí dojít. Představuji si naivní situaci, kdy jedna funkce v sobě volá jinou funkci, která čeká na vrácení hodnoty předchozí funkce. Každopádně, když použiji dvě funkce (forknuté ze stejného IO), které čtou ze stejného souboru (zamčeného), tak se prostě zaseknou bez ohledu na to, že jsou monadické. (Trošku vařím z vody, k forkIO jsem se ještě nedostal.) A vzhledem k tomu, že se zaseknou, tak je porušena funkcionálnost.

Citace
Jako ve výsledku vlastně jde jen o to, že když něco nazveš nějak, tak od toho taky něco očekáváš. A když od jazyka, který o sobě tvrdí, že je pure funkcional, a on pak ve skutečnosti není, tak to naštve. Když by se řeklo, že Haskell je "pure funkcional s výhradou", tak by byl třeba čumil spokojenej.

Ale Safe Haskell s IO monádou bez věcí jako unsafePerformIO, unsafeCoerce atd., je čistě funkcionální - definici splňuje bez výhrad (všechny výrazy tam jsou referenčně transparentní). Rovněž tam funguje substituční model, když zkoumáte chování programů.

Ale v normálním Haskellu tedy funkce jako unsafePerformIO, unsafeCoerce atd. jsou, takže takovej Haskell není čistě funkcionální. Obvykle se bavíme o Haskellu, ne o Safe Haskellu (to abyste mě neařkli ze slovíčkaření). I na wikině je, že Safe Haskell je čistě funkcionální. Na několika místech. Takže si dovedu představit jak se při čtení něčeho takového musí čumil vztekat.

Bohužel o tom, jak funguje Uniqueness typing vím kulové, takže nemohu argumentovat. Chápal jsem to tak, že z nějaké, jakési, definice se musí jednat vždy o jednu instanci (představil jsem si to jak UID, u kterého by mě taky naštvalo, když by nějaká aplikace měla stejné jako já.) Pokud to tak není, tak budu jen rád, když se tu o tom rozkecáte podobně jako čumil :-)

JSH

Re:Funkcionální programátor
« Odpověď #157 kdy: 01. 07. 2015, 22:06:46 »
... ale už to nebude Uniqueness typing, protože jsi porušil pravidlo ohledně jediné instance.
Uniqueness typing nijak neomezuje počet instancí. Jen na každou z nich může být jenom jedna reference. Těch instancí světů může být klidně milion a uniqueness typing ani nepípne, pokud bude mít každá jen po jedné referenci na ni.

Uniqueness typing ani nemůže omezovat počet instancí, protože by se nedal využít u věcí jako jsou třeba soubory.

v

Re:Funkcionální programátor
« Odpověď #158 kdy: 01. 07. 2015, 22:10:12 »
unsafePerformIO
pro pořádek, Safe Haskell není jiný jazyk/dialekt, je to nastavení překladače
a s unsafePerformIO Haskell čistý není, ale GHC chce být užitečný a tak je občas pragmatický (což je protipól nábožensko fundamentalisktického)

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #159 kdy: 01. 07. 2015, 22:12:17 »
Pragmatickou stránku věci chápu.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Funkcionální programátor
« Odpověď #160 kdy: 01. 07. 2015, 22:17:10 »
... ale už to nebude Uniqueness typing, protože jsi porušil pravidlo ohledně jediné instance.
Uniqueness typing nijak neomezuje počet instancí. Jen na každou z nich může být jenom jedna reference. Těch instancí světů může být klidně milion a uniqueness typing ani nepípne, pokud bude mít každá jen po jedné referenci na ni.

Uniqueness typing ani nemůže omezovat počet instancí, protože by se nedal využít u věcí jako jsou třeba soubory.

Takže otevřu soubor, získám instanci na ten soubor (definovanou jako UT), takže ten soubor už nemůžu otevřít jinde a získat druhou instanci na ten souboru?

JSH

Re:Funkcionální programátor
« Odpověď #161 kdy: 01. 07. 2015, 22:35:00 »
Ale v normálním Haskellu tedy funkce jako unsafePerformIO, unsafeCoerce atd. jsou, takže takovej Haskell není čistě funkcionální. Obvykle se bavíme o Haskellu, ne o Safe Haskellu (to abyste mě neařkli ze slovíčkaření). I na wikině je, že Safe Haskell je čistě funkcionální. Na několika místech. Takže si dovedu představit jak se při čtení něčeho takového musí čumil vztekat.
Takhle prostě dopadá konflikt teoretické čistoty a praktických požadavků. Reálný svět je jedna obrovská smrdutá hromada stavu. Kromě unsafe funkcí má Haskell i FFI (může volat C funkce) a díky tomu se mu dá vnutit cokoliv. FFI má i clean. Navíc nedokumentované, takže je to dvojnásobná past. Díky FFI bychom i o cleanu mohli tvrdit, že při fanatické aplikaci definic není čistě funkcionální. Akorát by to k ničemu nebylo.
Citace
Bohužel o tom, jak funguje Uniqueness typing vím kulové, takže nemohu argumentovat. Chápal jsem to tak, že z nějaké, jakési, definice se musí jednat vždy o jednu instanci (představil jsem si to jak UID, u kterého by mě taky naštvalo, když by nějaká aplikace měla stejné jako já.) Pokud to tak není, tak budu jen rád, když se tu o tom rozkecáte podobně jako čumil :-)
Jestli znáš C++, tak uniqueness typing trochu odpovídá move semantice. Na každý objekt je jedna jediná reference. Objekty se tak dají třeba modifikovat, protože se žádné jiné referenci nezmění pod rukama.

Takže otevřu soubor, získám instanci na ten soubor (definovanou jako UT), takže ten soubor už nemůžu otevřít jinde a získat druhou instanci na ten souboru?
Jestli se soubor nedá otevřít jinde musí hlídat OS. Protože musí hlídat i jiné procesy. Je to o něčem jiném.
Pokud soubor otevřu pro čtení, tak nemusí být unikátní. Můžu si handle zkopírovat a ten soubor předat 10 různým funkcím. Na všech místech dostanu stejná data.
Pokud otevřu soubor pro čtení i zápis, tak dostanu unikátní referenci na něj. Teď ten soubor nemůžu číst z více míst, protože zápis z jednoho místa by ten soubor změnil a na druhém míste bych dostal jiná data. Další funkci ho můžu předat až mi ho ta první zase vrátí. Samozřejmě se to dá obejít, třeba ten soubor otevřít vícekrát. Takže to chrání hlavně před chybami.

Radek Miček

Re:Funkcionální programátor
« Odpověď #162 kdy: 01. 07. 2015, 22:46:53 »
Mě tam zase zaujalo to vztekání se ohledně Race Condition. Je fakt, že když je něco funkcionální podle té čumilově definice, tak k souběhu nesmí dojít. Představuji si naivní situaci, kdy jedna funkce v sobě volá jinou funkci, která čeká na vrácení hodnoty předchozí funkce. Každopádně, když použiji dvě funkce (forknuté ze stejného IO), které čtou ze stejného souboru (zamčeného), tak se prostě zaseknou bez ohledu na to, že jsou monadické. (Trošku vařím z vody, k forkIO jsem se ještě nedostal.) A vzhledem k tomu, že se zaseknou, tak je porušena funkcionálnost.

Ty funkce se nezaseknou - normálně doběhnou a vrátí hodnotu typu IO a pro nějaké a. Vrácené hodnoty se pak skombinují pomocí >>= z IO monády a vznikne jedna obří hodnota IO () - tu vrátí funkce main - žádný vedlejší efekt se neprovede, nic se nezasekne.
Citace
Ale v normálním Haskellu tedy funkce jako unsafePerformIO, unsafeCoerce atd. jsou, takže takovej Haskell není čistě funkcionální. Obvykle se bavíme o Haskellu, ne o Safe Haskellu (to abyste mě neařkli ze slovíčkaření).

Ty funkce jsou rozšíření GHC Haskellu, v Haskell 2010 Language Report o nich není ani zmínka - je tam však FFI a některá chování tam nejsou definována - v těchto případech Haskell nemusí být čistě funkcionální.

Citace
Chápal jsem to tak, že z nějaké, jakési, definice se musí jednat vždy o jednu instanci

Obecně typový systém nic (takového) negarantuje. Například, říká-li typový systém, že výraz má typ int, neznamená to, že když výraz vyhodnotíte, tak dostanete celé číslo - klidně můžete dostat řetězec nebo instanci třídy Pes nebo něco úplně jiného.

Celé číslo byste dostal, pokud by byl typový systém korektní (sound) vzhledem k nějaké (operační) sémantice.

v

Re:Funkcionální programátor
« Odpověď #163 kdy: 01. 07. 2015, 22:53:58 »
Mě tam zase zaujalo to vztekání se ohledně Race Condition. Je fakt, že když je něco funkcionální podle té čumilově definice, tak k souběhu nesmí dojít. Představuji si naivní situaci, kdy jedna funkce v sobě volá jinou funkci, která čeká na vrácení hodnoty předchozí funkce. Každopádně, když použiji dvě funkce (forknuté ze stejného IO), které čtou ze stejného souboru (zamčeného), tak se prostě zaseknou bez ohledu na to, že jsou monadické. (Trošku vařím z vody, k forkIO jsem se ještě nedostal.) A vzhledem k tomu, že se zaseknou, tak je porušena funkcionálnost.

Ty funkce se nezaseknou - normálně doběhnou a vrátí hodnotu typu IO a pro nějaké a. Vrácené hodnoty se pak skombinují pomocí >>= z IO monády a vznikne jedna obří hodnota IO () - tu vrátí funkce main - žádný vedlejší efekt se neprovede, nic se nezasekne.


já bych řekl, že třeba systémové volání v IO se zaseknout může

Radek Miček

Re:Funkcionální programátor
« Odpověď #164 kdy: 01. 07. 2015, 22:54:18 »
Mě tam zase zaujalo to vztekání se ohledně Race Condition. Je fakt, že když je něco funkcionální podle té čumilově definice, tak k souběhu nesmí dojít. Představuji si naivní situaci, kdy jedna funkce v sobě volá jinou funkci, která čeká na vrácení hodnoty předchozí funkce. Každopádně, když použiji dvě funkce (forknuté ze stejného IO), které čtou ze stejného souboru (zamčeného), tak se prostě zaseknou bez ohledu na to, že jsou monadické. (Trošku vařím z vody, k forkIO jsem se ještě nedostal.) A vzhledem k tomu, že se zaseknou, tak je porušena funkcionálnost.

Ty funkce se nezaseknou - normálně doběhnou a vrátí hodnotu typu IO a pro nějaké a. Vrácené hodnoty se pak skombinují pomocí >>= z IO monády a vznikne jedna obří hodnota IO () - tu vrátí funkce main - žádný vedlejší efekt se neprovede, nic se nezasekne.

Jinak řečeno, čistě funkcionální není interpretr, který interpretuje hodnotu typu IO (), jenž vrátila funkce main. Naštěstí ten interpretr není součástí vašeho programu nebo jazyka - nemáte k němu přístup (až na unsafePerformIO apod.).