Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Speedy 22. 08. 2018, 14:35:49

Název: Rychlost Haskell vs. C++
Přispěvatel: Speedy 22. 08. 2018, 14:35:49
Když Wadler (a to je nějaká kapacita) tvrdí, že Haskell je rychlejší než C++, čím to může být? Nějaké extra optimalizace?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: optimizer 22. 08. 2018, 14:44:20
nějaký benchmark? Čekám další teoretickou diskuzi pseudointelektuálů.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: oss 22. 08. 2018, 17:20:14
To cakam aj ja.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: haskell 22. 08. 2018, 18:12:34
https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/ghc-gpp.html
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: hawran diskuse 22. 08. 2018, 21:27:27
OMG

Ferari je prý rychlejší lakatoš.
Ale já musím jezdit po rozbitých lesních cestách a stahovat dřevo...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Hashgap 22. 08. 2018, 23:35:13
Nějaké extra optimalizace?
Wadler asi myslel rychlost psaní kódu. Běh záleží na použitých datových strukturách, nicméně třeba seznamy nebo hashmapy jsou ve FP v praxi stejně rychlé jako v C++.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: optimizer 22. 08. 2018, 23:50:49
Nějaké extra optimalizace?
Wadler asi myslel rychlost psaní kódu. Běh záleží na použitých datových strukturách, nicméně třeba seznamy nebo hashmapy jsou ve FP v praxi stejně rychlé jako v C++.

seznamy jsou stejně pomalé všude, mimo FP se moc nepožívají. Mutable hashmapy v FP nejdou.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Hashgap 23. 08. 2018, 00:17:49
Nějaké extra optimalizace?
Wadler asi myslel rychlost psaní kódu. Běh záleží na použitých datových strukturách, nicméně třeba seznamy nebo hashmapy jsou ve FP v praxi stejně rychlé jako v C++.
Mutable hashmapy v FP nejdou.
Nikdo nemluvil o mutable. Proč reaguješ kravinama na něco, o čem nic nevíš?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JS 23. 08. 2018, 11:02:09
V obojim (Haskell i C++) se da psat rychly kod, pokud pouzijes dostatek usili. Je to cele jen o tom, ze C++ je jazyk nizsi urovne nez Haskell. Takze jednoduchy algoritmus, co nejak napises, bude pravdepodobne v C++ az o rad rychlejsi nez v Haskellu. Ale s tim, jak bude rust slozitost algoritmu nebo obecne toho, co delas, v Haskellu bude jednodussi dosahnout vyssiho vykonu (to neznamena, ze v C++ to nejde, jen to bude stat vetsi usili).

(Je mozne si predstavit analogickou situaci mezi assemblerem a C++, pro male programy je rucne psany assembler potencialne rychlejsi, ale tato vyhoda spatne skaluje.)

Haskell sam provadi nektere optimalizace, treba stream fusion (v podstate se da rict, ze je to slucovani smycek), ktere kompilatory nizsich jazyku obvykle nedelaji. Muzes je delat v ruce, ale to spatne skaluje s velikosti programu.

Dalsi vec je vyhodnocovani a s tim spojeny tradeoff (a to ma asi Wadler na mysli). Line vyhodnocovani je obecne pomalejsi pokud musime nejakou strukturu vyhodnotit celou, ale muze byt rychlejsi pokud ji nechceme vzdy vyhodnotit celou. V nekterych pripadech muze byt tedy program v Haskellu, co vyhodnocuje line, daleko rychlejsi nez program v C++, ktery vyhodnocuje striktne.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Kiwi 23. 08. 2018, 11:40:27
V obojim (Haskell i C++) se da psat rychly kod, pokud pouzijes dostatek usili. Je to cele jen o tom, ze C++ je jazyk nizsi urovne nez Haskell. Takze jednoduchy algoritmus, co nejak napises, bude pravdepodobne v C++ az o rad rychlejsi nez v Haskellu. Ale s tim, jak bude rust slozitost algoritmu nebo obecne toho, co delas, v Haskellu bude jednodussi dosahnout vyssiho vykonu (to neznamena, ze v C++ to nejde, jen to bude stat vetsi usili).

(Je mozne si predstavit analogickou situaci mezi assemblerem a C++, pro male programy je rucne psany assembler potencialne rychlejsi, ale tato vyhoda spatne skaluje.)

Haskell sam provadi nektere optimalizace, treba stream fusion (v podstate se da rict, ze je to slucovani smycek), ktere kompilatory nizsich jazyku obvykle nedelaji. Muzes je delat v ruce, ale to spatne skaluje s velikosti programu.

Dalsi vec je vyhodnocovani a s tim spojeny tradeoff (a to ma asi Wadler na mysli). Line vyhodnocovani je obecne pomalejsi pokud musime nejakou strukturu vyhodnotit celou, ale muze byt rychlejsi pokud ji nechceme vzdy vyhodnotit celou. V nekterych pripadech muze byt tedy program v Haskellu, co vyhodnocuje line, daleko rychlejsi nez program v C++, ktery vyhodnocuje striktne.
No, nevim...
https://stackoverflow.com/questions/7717691/why-is-the-minimalist-example-haskell-quicksort-not-a-true-quicksort
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 23. 08. 2018, 13:11:24
V obojim (Haskell i C++) se da psat rychly kod, pokud pouzijes dostatek usili. Je to cele jen o tom, ze C++ je jazyk nizsi urovne nez Haskell. Takze jednoduchy algoritmus, co nejak napises, bude pravdepodobne v C++ az o rad rychlejsi nez v Haskellu. Ale s tim, jak bude rust slozitost algoritmu nebo obecne toho, co delas, v Haskellu bude jednodussi dosahnout vyssiho vykonu (to neznamena, ze v C++ to nejde, jen to bude stat vetsi usili).
Jinými slovy tvrdíš, že jednoduché alogitmy Haskell překladač optimalizovat neumí a složité ano. Ne, takhle to v praxi opravdu nefunguje...

(Je mozne si predstavit analogickou situaci mezi assemblerem a C++, pro male programy je rucne psany assembler potencialne rychlejsi, ale tato vyhoda spatne skaluje.)
Doba, kdy byl ručně napsaný kód v assembleru rychlejší, než kód vygenerovaný překladačem, je dávno pryč. Dnešní CPU s dlouhou pipeline a spekulativním vyhodnocováním mají spoustu pravidel omezujících vykonávání instrukcí, které když se nedodrží, tak je kód pomalý. Člověk to rozumně nedokáže udržet v hlavě, překladač ano. V assembleru už má smysl psát jen SIMD kód, tohle překladače ještě úplně dobře nedávají.

Dalsi vec je vyhodnocovani a s tim spojeny tradeoff (a to ma asi Wadler na mysli). Line vyhodnocovani je obecne pomalejsi pokud musime nejakou strukturu vyhodnotit celou, ale muze byt rychlejsi pokud ji nechceme vzdy vyhodnotit celou. V nekterych pripadech muze byt tedy program v Haskellu, co vyhodnocuje line, daleko rychlejsi nez program v C++, ktery vyhodnocuje striktne.
Jenom v tom případě, když je kód v C++ napsaný blbě a vyhodnocuje i to, co nemusí. V runtime je jasné, co se musí vyhodnotit a co ne. Pokud se vyhodnocuje i něco navíc, je to chyba v programu. Haskell má výhodu, že to řeší automaticky, ale líne vyhodnocování má zase jiné nedostatky, např. bookkeeping overhead a horší lokalitu dat jak v instrukční, tak v datové cache, protože data se s líným vyhodnocováním nezpracovávají najednou na jednom místě, ale "po kouskách" postupně na mnoha místech.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JS 23. 08. 2018, 13:12:53
No, nevim...
https://stackoverflow.com/questions/7717691/why-is-the-minimalist-example-haskell-quicksort-not-a-true-quicksort

Co nevis? Vzdyt o tom presne pisu - pokud zkusis napsat (jednoduchy) algoritmus "naivne" v C++ a Haskellu, ten Haskell bude pravdepodobne pomalejsi.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JS 23. 08. 2018, 13:22:08
Jinými slovy tvrdíš, že jednoduché alogitmy Haskell překladač optimalizovat neumí a složité ano. Ne, takhle to v praxi opravdu nefunguje...
Netvrdim. To co tvrdim je, ze Haskell automatizuje nektere optimalizace, ktere musis v C++ delat rucne, ale ta automatizace se projevi az na vetsich programech. Neni to o tom, ze by ty jednoduche neumel.

Citace
Doba, kdy byl ručně napsaný kód v assembleru rychlejší, než kód vygenerovaný překladačem, je dávno pryč. Dnešní CPU s dlouhou pipeline a spekulativním vyhodnocováním mají spoustu pravidel omezujících vykonávání instrukcí, které když se nedodrží, tak je kód pomalý. Člověk to rozumně nedokáže udržet v hlavě, překladač ano. V assembleru už má smysl psát jen SIMD kód, tohle překladače ještě úplně dobře nedávají.
S tim souhlasim. A totez bude jednou platit pro Haskell a C++ (nebude se vyplacet psat v C++ protoze kompilator Haskellu - nebo jineho vyssiho jazyka - bude temer vzdy chytrejsi); je to jen otazka casu.

Citace
Jenom v tom případě, když je kód v C++ napsaný blbě a vyhodnocuje i to, co nemusí. V runtime je jasné, co se musí vyhodnotit a co ne. Pokud se vyhodnocuje i něco navíc, je to chyba v programu. Haskell má výhodu, že to řeší automaticky, ale líne vyhodnocování má zase jiné nedostatky, např. bookkeeping overhead a horší lokalitu dat jak v instrukční, tak v datové cache, protože data se s líným vyhodnocováním nezpracovávají najednou na jednom místě, ale "po kouskách" postupně na mnoha místech.
S tim souhlasim a je to jen jinymi slovy to, co jsem napsal. To, co rikam navic je, ze napsat ten kod v C++ spravne (ve smyslu ne-blbe) je slozitejsi nez napsat ho spravne v Haskellu, protoze C++ je jazyk nizsi urovne.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 23. 08. 2018, 13:47:52
S tim souhlasim. A totez bude jednou platit pro Haskell a C++ (nebude se vyplacet psat v C++ protoze kompilator Haskellu - nebo jineho vyssiho jazyka - bude temer vzdy chytrejsi); je to jen otazka casu.
To je věštení z křišťálové koule, kterou nemáš. Přitom vůbec nebereš v úvahu fundamentální odlišnosti Haskellu, které jsou dané líným vyhodnocováním. Líné vyhodnocování je největší deviza a zároveň prokletí Haskellu, protože přímo diktuje způsob zpracování dat. Žravé vyhodnocování vezme nějaký balík dat a přetransformuje je všechny najednou A -> B. Potom vezme znovu ten velký balík dat a přetransformuje je znovu B -> C. Líné vyhodnocování to bude dělat po jednotlivých prvcích A1 -> B1 -> C1, A2 -> B2 -> C2, ... Teoreticky je složitost žravého i líného vyhodnocení stejná, ale ten žravý způsob je na standardním hardware obvykle o hodně rychlejší kvůli lepšímu využití cache. V C++ si můžu vybrat, jestli konkrétní algoritmus implementuji líně nebo žravě, v Haskellu si moc vybírat nemůžu. I v Haskellu by to asi šlo napsat tak, aby se výpočet efektivně prováděl žravě, ale je to tak trochu hack, který jde proti filozofii jazyka a stejně se bude i v takovém připadě líné vyhodnocování řešit někde na pozadí, i když není vůbec potřeba. Líného vyhodnocování se v Haskellu moc nejde zbavit a je to overhead navíc.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Kit 23. 08. 2018, 13:59:25
No, nevim...
https://stackoverflow.com/questions/7717691/why-is-the-minimalist-example-haskell-quicksort-not-a-true-quicksort

Otázkou zůstává, proč by někdo v Haskellu programoval quicksort, když má svůj nativní sort. Pokud budeš požadovat implementaci algoritmu, imperativní jazyky by měly být rychlejší. Pokud budeš požadovat určitou funkcionalitu, budou mít navrch funkcionální jazyky.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 23. 08. 2018, 14:02:20
To je věštení z křišťálové koule, kterou nemáš. Přitom vůbec nebereš v úvahu fundamentální odlišnosti Haskellu, které jsou dané líným vyhodnocováním. Líné vyhodnocování je největší deviza a zároveň prokletí Haskellu, protože přímo diktuje způsob zpracování dat. Žravé vyhodnocování vezme nějaký balík dat a přetransformuje je všechny najednou A -> B. Potom vezme znovu ten velký balík dat a přetransformuje je znovu B -> C. Líné vyhodnocování to bude dělat po jednotlivých prvcích A1 -> B1 -> C1, A2 -> B2 -> C2, ... Teoreticky je složitost žravého i líného vyhodnocení stejná, ale ten žravý způsob je na standardním hardware obvykle o hodně rychlejší kvůli lepšímu využití cache.
Pokud jde jen o pořadí vyhodnocování, tak samotné líné vyhodnocování je pro cache lepší. Po A1->B1 máme B1 v cache a dává smysl ho hned použít a ne ho načítat znova až projedeme všechny A->B.
Problém je v tom, že pro implementaci líného vyhodnocování v Haskellu jsou třeba boxované hodnoty. Ty jednotlivé prvky jsou rozházené po paměti a prefetcher to úplně nedává.
V C++ se právě docela často používá spojování dílčích operací do jedné veliké přes expression templates třeba v knihovnách pro matice.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 23. 08. 2018, 14:16:17
Pokud jde jen o pořadí vyhodnocování, tak samotné líné vyhodnocování je pro cache lepší. Po A1->B1 máme B1 v cache a dává smysl ho hned použít a ne ho načítat znova až projedeme všechny A->B.
Není to lepší, protože A1 načte celou cache line. B1 načte taky celou cache line, stejně jako C1, D1, E1... Snadno se stane, že při vyhodnocení A2 už není A1 cache line v cache, protože ji vytlačily další data a čte se znovu z paměti. Stejný problém se týká i instrukční cache a branch predictoru, také mají omezenou velikost, která s hloubkou zanoření velmi rychle přeteče.

A znovu opakuji, v C++ si můžu vybrat, jestli zvolím líné nebo žravé vyhodnocení podle výhodnosti pro konkrétní úlohu, v Haskellu si moc vybírat nemůžu, jsem omezený líným vyhodnocením.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JS 23. 08. 2018, 14:19:12
S tim souhlasim. A totez bude jednou platit pro Haskell a C++ (nebude se vyplacet psat v C++ protoze kompilator Haskellu - nebo jineho vyssiho jazyka - bude temer vzdy chytrejsi); je to jen otazka casu.
To je věštení z křišťálové koule, kterou nemáš.
Rad bych napsal, ze kristalovou kouli doma mam, ale fakt je, ze nemam. Nicmene, da se urcite koupit..

Kazdopadne, jde mi o to, ze v podobne situaci jsme uz historicky byli s tim C++ a assemblerem, nekdy v 80. az 90. letech minuleho stoleti, a taky se o tom vedly velke debaty. A skoncilo to tim, ze automatizace (kompilator) vyhral. Stejne tak myslim (bez koule), ze vyhraje i v tomto pripade. (Haskellovy kompilator uz dnes dela treba strictness analyzu, viz https://wiki.haskell.org/Performance/Strictness (https://wiki.haskell.org/Performance/Strictness), takze minimalne v tomhle je napred pred C++ kompilatorem.)

Citace
Přitom vůbec nebereš v úvahu fundamentální odlišnosti Haskellu, které jsou dané líným vyhodnocováním.
Jak to, vzdyt jsem o tom v tomto vlakne zacal?

Citace
Líného vyhodnocování se v Haskellu moc nejde zbavit a je to overhead navíc.
Ja jsem si to driv taky myslel, ale dnes si myslim, ze to neni pravda a zbavit se jej lze docela pekne (a rozhodne myslim, ze je to jednodussi nez donutit C++ program chovat se line). Viz napriklad https://www.fpcomplete.com/blog/2017/09/all-about-strictness (https://www.fpcomplete.com/blog/2017/09/all-about-strictness). Mam za to, ze je to proste spis o zvyku. Jinak dobra knizka k tematu, co ted ctu, je https://www.packtpub.com/application-development/haskell-high-performance-programming (https://www.packtpub.com/application-development/haskell-high-performance-programming).
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 23. 08. 2018, 14:35:43
Pokud jde jen o pořadí vyhodnocování, tak samotné líné vyhodnocování je pro cache lepší. Po A1->B1 máme B1 v cache a dává smysl ho hned použít a ne ho načítat znova až projedeme všechny A->B.
A znovu opakuji, v C++ si můžu vybrat, jestli zvolím líné nebo žravé vyhodnocení podle výhodnosti pro konkrétní úlohu, v Haskellu si moc vybírat nemůžu, jsem omezený líným vyhodnocením.
Ano, Haskell je defaultně líný, ale v FP obecně si většinou můžu vybrat eager vs. lazy.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 23. 08. 2018, 14:36:24
Pokud jde jen o pořadí vyhodnocování, tak samotné líné vyhodnocování je pro cache lepší. Po A1->B1 máme B1 v cache a dává smysl ho hned použít a ne ho načítat znova až projedeme všechny A->B.
Není to lepší, protože A1 načte celou cache line. B1 načte taky celou cache line, stejně jako C1, D1, E1... Snadno se stane, že při vyhodnocení A2 už není A1 cache line v cache, protože ji vytlačily další data a čte se znovu z paměti. Stejný problém se týká i instrukční cache a branch predictoru, také mají omezenou velikost, která s hloubkou zanoření velmi rychle přeteče.
Tady samozřejmě hrozně záleží na tom, jak velké jsou ty prvky, jak složité jsou ty operace a na spoustě dalších věcí. Já chtěl jenom vypíchnout, že to žravé vyhodnocení nemusí být vždycky pro cache lepší a naopak se v maticových knihovnách (třeba C++ Eigen) ty dílčí operace běžně spojují do větších. Obzvlášt, když díky tomu to pole Bček může úplně zmizet.
Citace
A znovu opakuji, v C++ si můžu vybrat, jestli zvolím líné nebo žravé vyhodnocení podle výhodnosti pro konkrétní úlohu, v Haskellu si moc vybírat nemůžu, jsem omezený líným vyhodnocením.
I v tom Haskellu se dá (jakž takž) vybrat. Prvky struktur se dají anotovat jako striktní nebo dokonce neboxované.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 23. 08. 2018, 14:45:15
S tim souhlasim. A totez bude jednou platit pro Haskell a C++ (nebude se vyplacet psat v C++ protoze kompilator Haskellu - nebo jineho vyssiho jazyka - bude temer vzdy chytrejsi); je to jen otazka casu.
To je věštení z křišťálové koule, kterou nemáš.
Rad bych napsal, ze kristalovou kouli doma mam, ale fakt je, ze nemam. Nicmene, da se urcite koupit..

Kazdopadne, jde mi o to, ze v podobne situaci jsme uz historicky byli s tim C++ a assemblerem, nekdy v 80. az 90. letech minuleho stoleti, a taky se o tom vedly velke debaty. A skoncilo to tim, ze automatizace (kompilator) vyhral. Stejne tak myslim (bez koule), ze vyhraje i v tomto pripade. (Haskellovy kompilator uz dnes dela treba strictness analyzu, viz https://wiki.haskell.org/Performance/Strictness (https://wiki.haskell.org/Performance/Strictness), takze minimalne v tomhle je napred pred C++ kompilatorem.)

Citace
Přitom vůbec nebereš v úvahu fundamentální odlišnosti Haskellu, které jsou dané líným vyhodnocováním.
Jak to, vzdyt jsem o tom v tomto vlakne zacal?

Citace
Líného vyhodnocování se v Haskellu moc nejde zbavit a je to overhead navíc.
Ja jsem si to driv taky myslel, ale dnes si myslim, ze to neni pravda a zbavit se jej lze docela pekne (a rozhodne myslim, ze je to jednodussi nez donutit C++ program chovat se line). Viz napriklad https://www.fpcomplete.com/blog/2017/09/all-about-strictness (https://www.fpcomplete.com/blog/2017/09/all-about-strictness). Mam za to, ze je to proste spis o zvyku. Jinak dobra knizka k tematu, co ted ctu, je https://www.packtpub.com/application-development/haskell-high-performance-programming (https://www.packtpub.com/application-development/haskell-high-performance-programming).

Já nevím, mně to přijde celé ujeté. Haskell přišel s nějakým designových rozhodnotím (lazy evaluation), což má nějaké výhody a nevýhody. Během doby se přišlo na to, že lazy evaluation stojí docela dost výkonu, tak se hledalo, jak z toho ven. Transparentní optimalizace překladače beru, ty jsou v pohodě, ať si překladač klidně dělá strictness analyzu (kterou mimochodem C++ překladač na nic nepotřebuje) a vyhodí všechno, co nemusí být lazy, abych se o to nemusel starat, to je fajn. Ale proč se tím mám sakra zabývat jako uživatel a přemýšlet, jestli mám napsat foldl nebo foldl' a když náhodou na ten apostrof zapomenu, tak všechno bude zdánlivě fungovat, ale aplikace zhavaruje v nejméně vhodnou dobu v produkci, když dostane nějaká větší data? Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 23. 08. 2018, 14:57:59
Já nevím, mně to přijde celé ujeté. Haskell přišel s nějakým designových rozhodnotím (lazy evaluation), což má nějaké výhody a nevýhody. Během doby se přišlo na to, že lazy evaluation stojí docela dost výkonu, tak se hledalo, jak z toho ven. Transparentní optimalizace překladače beru, ty jsou v pohodě, ať si překladač klidně dělá strictness analyzu (kterou mimochodem C++ překladač na nic nepotřebuje) a vyhodí všechno, co nemusí být lazy, abych se o to nemusel starat, to je fajn. Ale proč se tím mám sakra zabývat jako uživatel a přemýšlet, jestli mám napsat foldl nebo foldl' a když náhodou na ten apostrof zapomenu, tak všechno bude zdánlivě fungovat, ale aplikace zhavaruje v nejméně vhodnou dobu v produkci, když dostane nějaká větší data? Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci.
Designových rozhodnutí, nad kterými musí programátor přemýšlet, má každý jazyk mraky. V produkci na větších datech chcípe i to C++. Stačí třeba uvolňovat větší strom smart pointerů.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 23. 08. 2018, 15:05:23
Designových rozhodnutí, nad kterými musí programátor přemýšlet, má každý jazyk mraky. V produkci na větších datech chcípe i to C++. Stačí třeba uvolňovat větší strom smart pointerů.
Jenomže v Haskellu je to narovnávák na ohýbák. Vývoj Haskellu: uděláme lazy evaluation, to bude super! (až doteď dobrý, já proti lazy evaluation v podstatě nic nemám :-)). No jo, ale ono to nefunguje vždycky optimálně, co s tím? Nějak to uděláme, aby lazy ve skutečnosti nebylo lazy... A ten způsob, jak to do jazyka implementovali, je podlě mě nešťastný.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 23. 08. 2018, 18:12:31
Já nevím, mně to přijde celé ujeté. Haskell přišel s nějakým designových rozhodnotím (lazy evaluation), což má nějaké výhody a nevýhody. Během doby se přišlo na to, že lazy evaluation stojí docela dost výkonu, tak se hledalo, jak z toho ven. Transparentní optimalizace překladače beru, ty jsou v pohodě, ať si překladač klidně dělá strictness analyzu (kterou mimochodem C++ překladač na nic nepotřebuje) a vyhodí všechno, co nemusí být lazy, abych se o to nemusel starat, to je fajn. Ale proč se tím mám sakra zabývat jako uživatel a přemýšlet, jestli mám napsat foldl nebo foldl' a když náhodou na ten apostrof zapomenu, tak všechno bude zdánlivě fungovat, ale aplikace zhavaruje v nejméně vhodnou dobu v produkci, když dostane nějaká větší data? Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci.
Designových rozhodnutí, nad kterými musí programátor přemýšlet, má každý jazyk mraky. V produkci na větších datech chcípe i to C++. Stačí třeba uvolňovat větší strom smart pointerů.
Strom smart pointerů a normálních pointerů na tom jsou stejně.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 23. 08. 2018, 20:47:12
Já nevím, mně to přijde celé ujeté. Haskell přišel s nějakým designových rozhodnotím (lazy evaluation), což má nějaké výhody a nevýhody. Během doby se přišlo na to, že lazy evaluation stojí docela dost výkonu, tak se hledalo, jak z toho ven. Transparentní optimalizace překladače beru, ty jsou v pohodě, ať si překladač klidně dělá strictness analyzu (kterou mimochodem C++ překladač na nic nepotřebuje) a vyhodí všechno, co nemusí být lazy, abych se o to nemusel starat, to je fajn. Ale proč se tím mám sakra zabývat jako uživatel a přemýšlet, jestli mám napsat foldl nebo foldl' a když náhodou na ten apostrof zapomenu, tak všechno bude zdánlivě fungovat, ale aplikace zhavaruje v nejméně vhodnou dobu v produkci, když dostane nějaká větší data? Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci.
Designových rozhodnutí, nad kterými musí programátor přemýšlet, má každý jazyk mraky. V produkci na větších datech chcípe i to C++. Stačí třeba uvolňovat větší strom smart pointerů.
Strom smart pointerů a normálních pointerů na tom jsou stejně.
Já tím myslel klasický bug, kdy objekty mají smart pointery na další objekty a destruktory se volají rekurzivně až občas přeteče zásobník. U smart pointerů je to víc zákeřné, protože tam ta rekurze v destruktorech není na první pohled vidět.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 01:35:34
Jenomže v Haskellu je to narovnávák na ohýbák. Vývoj Haskellu: uděláme lazy evaluation, to bude super! (až doteď dobrý, já proti lazy evaluation v podstatě nic nemám :-)). No jo, ale ono to nefunguje vždycky optimálně, co s tím? Nějak to uděláme, aby lazy ve skutečnosti nebylo lazy... A ten způsob, jak to do jazyka implementovali, je podlě mě nešťastný.
Nechápu. V jazyce, který je defaultně strict musíš dělat opičárny, pokud to chceš lazy. V Haskellu holt musíš dělat opičárny, pokud to chceš strict. Mně to přijde prašť jako uhoď - a default lazy je na spoustu věcí fakt pěkná záležitost (tying the knot).

On je třeba problém, že seq není referenčně transparentní - na druhou stranu ono to je prakticky vždycky jedno.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 11:03:57
Nechápu. V jazyce, který je defaultně strict musíš dělat opičárny, pokud to chceš lazy. V Haskellu holt musíš dělat opičárny, pokud to chceš strict. Mně to přijde prašť jako uhoď - a default lazy je na spoustu věcí fakt pěkná záležitost (tying the knot).
Reálně obvykle řešíš problém, jestli chceš nějaký balík dat zpracovat najednou, nebo postupně. Ve strict jazyce je to přímočaré v obou případech:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_b[i++] = foo(a);
}
i = 0;
for (b : pole_b) {
    pole_c[i++] = bar(b);
}
nebo:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_c[i++] = bar(foo(a));
}
Někdy je výhodnější první varianta, jindy druhá. Musím explicitně zvolit, jakou chci, ale obě řešení jsou jasná a přímočará. Haskell je defaultně lazy a nejde to vypnout. Ano i Haskell můžu přinutit, aby lazy nebyl, ale je to narovnávák na ohýbák, ten jazyk nebyl navržený na to, aby byl strict, je pořád lazy, i když ho přinutím spočítat něco "předčasně".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 11:59:36
Nechápu. V jazyce, který je defaultně strict musíš dělat opičárny, pokud to chceš lazy. V Haskellu holt musíš dělat opičárny, pokud to chceš strict. Mně to přijde prašť jako uhoď - a default lazy je na spoustu věcí fakt pěkná záležitost (tying the knot).
Reálně obvykle řešíš problém, jestli chceš nějaký balík dat zpracovat najednou, nebo postupně. Ve strict jazyce je to přímočaré v obou případech:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_b[i++] = foo(a);
}
i = 0;
for (b : pole_b) {
    pole_c[i++] = bar(b);
}
nebo:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_c[i++] = bar(foo(a));
}
Někdy je výhodnější první varianta, jindy druhá. Musím explicitně zvolit, jakou chci, ale obě řešení jsou jasná a přímočará. Haskell je defaultně lazy a nejde to vypnout. Ano i Haskell můžu přinutit, aby lazy nebyl, ale je to narovnávák na ohýbák, ten jazyk nebyl navržený na to, aby byl strict, je pořád lazy, i když ho přinutím spočítat něco "předčasně".
nestačí tohle https://ghc.haskell.org/trac/ghc/wiki/StrictPragma#Strict ?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 12:48:46
nestačí tohle https://ghc.haskell.org/trac/ghc/wiki/StrictPragma#Strict ?

Chápu motivaci, proč to udělali. Ale když si přečteš tohle: http://blog.johantibell.com/2015/11/the-design-of-strict-haskell-pragma.html, tak zjistíš, že je to zase jenom narovnávák na ohýbák. Jiný způsob, jak donutit jazyk, který je defaultně lazy a vždycky bude lazy, aby byl někdy strict. Což má samozřejmě některé nepříjemné vedlejší efekty, nejde to použít slepě, musí se u toho přemýšlet, protože spousta kódu závisí na tom, že se vyhodnocuje lazy a ne strict.

Přitom jediná motivace k takovým opičárnám je výkon. Lazy vyhodnocení je super, ale nepoužitelné pro high performace kód. Takže se to nějak udělá...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 12:59:31
Takže se to nějak udělá...
no a kde je problém?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 13:17:34
no a kde je problém?
Je to řešení, které jde proti návrhu jazyka a nejde použít na kód, který závisí na lazy vyhodnocení (což bude většina knihoven). Respektive ono se to asi vždycky přeloží, ale kód, který závisí na lazy vyhodnocení, to rozbije až v runtime. Takže musíš přemýšlet, který kód na lazy vyhodnocení závisí a který ne a doufat, žes to pochopil správně. Pokud ne, možná to spadne až v produkci. Pokud jsi s tím smířený, tak není problém.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 13:43:25
Nechápu. V jazyce, který je defaultně strict musíš dělat opičárny, pokud to chceš lazy. V Haskellu holt musíš dělat opičárny, pokud to chceš strict. Mně to přijde prašť jako uhoď - a default lazy je na spoustu věcí fakt pěkná záležitost (tying the knot).
Reálně obvykle řešíš problém, jestli chceš nějaký balík dat zpracovat najednou, nebo postupně. Ve strict jazyce je to přímočaré v obou případech:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_b[i++] = foo(a);
}
i = 0;
for (b : pole_b) {
    pole_c[i++] = bar(b);
}
nebo:
Kód: [Vybrat]
i = 0;
for (a : pole_a) {
    pole_c[i++] = bar(foo(a));
}
Někdy je výhodnější první varianta, jindy druhá. Musím explicitně zvolit, jakou chci, ale obě řešení jsou jasná a přímočará. Haskell je defaultně lazy a nejde to vypnout. Ano i Haskell můžu přinutit, aby lazy nebyl, ale je to narovnávák na ohýbák, ten jazyk nebyl navržený na to, aby byl strict, je pořád lazy, i když ho přinutím spočítat něco "předčasně".
No, v haskellu by to bylo něco ve stylu:
Kód: [Vybrat]
f = fmap foo . fmap bar
vs.
f = fmap (foo . bar)
jenomže - tyhle zápisy jsou ekvivalentní, optimalizátor to ví a bůhví co z něj vyleze. Ale tady žádné lazy vs. strict nevidím, tohle obojí je skládání funkcí, v Purescriptu (který je strict) se to bude chovat principiálně stejně. Problém je spíš v tom, že haskell je tak high-level, že ty pořádně nemůžeš ovlivnit, jestli se to vykoná prvním nebo druhým způsobem - bez ohledu na striktnost.

Příklad lazy kódu:
Kód: [Vybrat]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

Nebo třeba tohle: https://github.com/quchen/articles/blob/master/loeb-moeb.md (https://github.com/quchen/articles/blob/master/loeb-moeb.md)

Jak to uděláš ve strict jazyce? Docela velkou opičárnou....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 14:11:59
Problém je spíš v tom, že haskell je tak high-level, že ty pořádně nemůžeš ovlivnit, jestli se to vykoná prvním nebo druhým způsobem - bez ohledu na striktnost.
V Haskellu se to vždycky vykoná lazy způsobem, to je jasně definované, pokud teda nepoužiješ různé špinavé triky, jako třeba strict pragma, abys Haskell donutil ke strict chování.

Příklad lazy kódu:
Kód: [Vybrat]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

Nebo třeba tohle: https://github.com/quchen/articles/blob/master/loeb-moeb.md (https://github.com/quchen/articles/blob/master/loeb-moeb.md)

Jak to uděláš ve strict jazyce? Docela velkou opičárnou....

Hezké. Ale taky brutálně pomalé: https://chrisdone.com/posts/twitter-problem-loeb. Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 14:24:00
no a kde je problém?
Je to řešení, které jde proti návrhu jazyka a nejde použít na kód, který závisí na lazy vyhodnocení (což bude většina knihoven). Respektive ono se to asi vždycky přeloží, ale kód, který závisí na lazy vyhodnocení, to rozbije až v runtime. Takže musíš přemýšlet, který kód na lazy vyhodnocení závisí a který ne a doufat, žes to pochopil správně. Pokud ne, možná to spadne až v produkci. Pokud jsi s tím smířený, tak není problém.
tak ono se to použije jenom na zvolené moduly, ne na knihovny
a problém s tím nemám, s ne/striktností jsem nikdy problém neměl
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 14:33:18
a problém s tím nemám, s ne/striktností jsem nikdy problém neměl
v tom smylu, že možná nepíšu kód, který by na to byl háklivý
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 24. 08. 2018, 14:41:00
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 14:55:46
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 14:58:47
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
ne že by to v Cčku nešlo, třeba přeložit každý soubor s jiným nastavením zarovnání dat
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 15:02:46
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
ne že by to v Cčku nešlo, třeba přeložit každý soubor s jiným nastavením zarovnání dat
To je jenom špané nastavení překladače bez vazby na zdrojový kód. Pragma strict v Haskellu dělá něco mnohem horšího, mění sémantiku existujícího kódu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 24. 08. 2018, 15:07:35
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde.
V C nám nejde o strict, ale o lazy kód.
Ten jde IMHO rozbít docela snadno. Prostě si lazy načtu data a předpokládám, a když je načtu znova, tak očekávám (ten knihovní kód očekává), že se nepoužije cache. Nějaký side-effect, etc.

Viděl bych v tom stejnou opičárnou jako v Haskellu. Jen je to naopak.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 15:07:46
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.

Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde.
Výhoda C - když bys potřeboval lazy, tak to neumí... Nevýhoda haskellu - když potřebuješ strict, tak na to má direktivu, ale je to narovnávák na ohýbák....

Citace
V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 15:21:10
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.
Pointa je v tom, že typicky chceš strict a ne lazy. Lazy jsou pokud vím jen Haskell a Miranda, všechny novější jazyky jsou strict, jen někdy umožňují i lazy, líbí se mi třeba řešení v OCamlu.

Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů. A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 15:29:06
Hele ale to je jasný, že striktní kód, který bude dělat úplně přesně to samý jako ten lazy kód jenom bez toho lazy overheadu bude rychlejší. Ale ta pointa je, že když budeš chtít udělat něco lazy (viz ten loeb) v C, tak to dělat vůbec takhle nebudeš. Uděláš nějakou opičárnu.
Pointa je v tom, že typicky chceš strict a ne lazy. Lazy jsou pokud vím jen Haskell a Miranda, všechny novější jazyky jsou strict, jen někdy umožňují i lazy, líbí se mi třeba řešení v OCamlu.
No úplně typický haskellovský trik:
Kód: [Vybrat]
for_ [1..] $ \i ->
Tohle fakt strict nechceš. Ono v haskellu nemáš cykly, funguje to tam trošku reverzně, a to výše uvedené je v podstatě streaming, který nakonec používáš docela často...

Citace
Tohle není pravda. Když ve SVÉM modulu nastavíš tyhle pragmy tak tím nic nerozbiješ.
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů.
Dělal jsi to někdy? Problém lazy vs. strict je typicky jenom tehdy, pokud je nějaké větev, která se nemá vrátit, bottom. Ale to je typicky záležitost knihoven typu nějaký hodně specifický monady, různé exception handlingy a podobně. V knihovnách, které "něco dělají" (a je tam očekávatelný bottleneck) se tohle prakticky nevyskytuje.

Citace
A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...
A napíše to za 3násobný čas co já a ještě mu to bude padat. Jasně, je to vždycky trade-off. Hele já jsem se s tím, že by moje věci byly nějak brutálně závislé na výkonu CPU setkal relativně zřídka. Občas se to stane, a pak se vyplatí nějakou konkrétní část přepsat v něčem, co je prostě rychlejší, ale u drtivé většiny věcí fakt nejdeš s výkonem na krev (samozřejmě je otázka co děláš, pokud jo, tak třeba ten OCaml klidně může mít smysl).
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 15:44:36
No úplně typický haskellovský trik:
Kód: [Vybrat]
for_ [1..] $ \i ->
Tohle fakt strict nechceš. Ono v haskellu nemáš cykly, funguje to tam trošku reverzně, a to výše uvedené je v podstatě streaming, který nakonec používáš docela často...
No a o tom to celé je. Protože je Haskell lazy, píše se v něm kód, který funguje jen při lazy vyhodnocení a při strict ne. Na to není nic špatného. Jenom je potřeba počítat s tím, že lazy vyhodnocení má z principu vyšší overhead. To se vědělo od začátku. Pak ale někomu začalo vadit, že je Haskell moc pomalý a přemýšlel, jak ho zrychlit. Tak třeba bychom mohli udělat Haskell trochu strict... Co na tom, že rozbijeme existující kód... Mně se Haskell líbí, ale věci jako pragma strict jdou proti jeho designové čistotě a po pravdě moc nechápu, jak někdo z Haskell komunity může takovou věc obhajovat ;). Chápu důvody vzniku, nepřenesu se ale přes fakt, že to jde proti designu a filozofii jazyka, jen kvůli řešení výkonnostních problémů.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 24. 08. 2018, 16:30:59
Když píšeš nějakou aplikaci, používáš jenom svoje moduly nebo i něco externího? Typicky je toho externího řádově víc. Jednou přijde zákazník a řekne ti, že je to moc pomalé, potřebují spoustu serverů, které stojí spoustu peněz, aby to mohli provozovat. Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď, můžu do ní přidat pragma strict nebo nemůžu...? Nevíš, musíš ji kompletně nastudovat a pochopit a potom doufat, že jsi náhodou něco nepřehlídnul. Nebo prostě zákazníkovi říct, že má smůlu a ať si koupí víc serverů. A on si poptá řešení od někoho jiného, který to napíše ve strict jazyce a bude těch serverů potřebovat jen polovinu...
A když píšeš nějakou aplikaci ve striktním jazyce, používáš jenom svoje moduly, nebo i něco externího? ... Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď co? Abys ji mohl nějak zrychlit tak ji musíš kompletně nastudovat tak jak tak.

Máš pocit, že většina knihoven ve striktních jazycích je výborně napsaná a tenhle problém tam nehrozí?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 17:14:19
A když píšeš nějakou aplikaci ve striktním jazyce, používáš jenom svoje moduly, nebo i něco externího? ... Tak to zprofiluješ a zjistíš, že problém je v nějaké externí knihovně. A teď co? Abys ji mohl nějak zrychlit tak ji musíš kompletně nastudovat tak jak tak.
Nemusím ji kompletně nastudovat, protože nemám v plánu do knihovny přidávat "pragma strict". Stačí se zaměřit na problematické pasáže a s nimi něco udělat. Nebo můžu zkusit vypnout/zapnout nějaké optimalizace bez obav, že to rozbije existující kód. Haskell má ten problém, že zavedl optimalizační pragmu, která mění sémantiku kódu na úrovni modulu. Takže když ji chceš použít, musíš nastudovat minimálně ten konkrétní celý modul.

Máš pocit, že většina knihoven ve striktních jazycích je výborně napsaná a tenhle problém tam nehrozí?
Knihovna v Haskellu může být napsána úplně skvěle, ale stejně může být pomalá, protože lazy evaluation overhead. No a co teď s tím? Můžu tam dát pragma strict, nebo nemůžu...?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 24. 08. 2018, 17:31:46
Motáme se pořád v kruhu. Lazy vyhodnocení je hezké, ale má nezanedbatelný overhead. Pokud chci, aby Haskell nebyl lazy, jde to udělat, ale je to narovnávák na ohýbák, lazy kód tím rozbiju.
Už to tu zaznělo. Proč v C striktnost není ohýbák? Když v C použiju lazy techniky, tak se mi nemůže stát, že tím něco rozbiju (dosáhnu nežádoucího chování)?
V C neexistuje žádný přepínač "pragma lazy", existující strict kód v C nijak rozbít nejde. V Haskellu existuje pragma strict, což rozbije spoustu existujícího kódu a to tak, že se sice přeloží, ale spadne to až v runtime. V Haskellu pragma strict existuje jenom z toho důvodu, že se snaží řešit performance problémy lazy evaluation. Proto je to narovnávák na ohýbák: zavedu něco, co mění defaultní chování vyhodnocování, aby to bylo (někdy) rychlejší a přitom rozbiju existující kód.
ne že by to v Cčku nešlo, třeba přeložit každý soubor s jiným nastavením zarovnání dat
To je jenom špané nastavení překladače bez vazby na zdrojový kód. Pragma strict v Haskellu dělá něco mnohem horšího, mění sémantiku existujícího kódu.
tak třeba strict aliasing :D
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 17:39:20
tak třeba strict aliasing :D
Ano to byla docela zásadní změna, nicméně je to definované ve standardu a veškerý nový kód by měl respektovat strict aliasing rules. Překladače implementovaly warningy, pokud nebyly strict aliasing rules dodrženy (nedokázaly to poznat vždy), takže přechod nebyl až tak bolestivý. Navíc kód, který nerespektoval strict aliasing rules, byl vždy považován za prasárnu a často byl také neportabilní, moc se to nevyskytovalo. S pragma strict v Haskellu to nejde úplně srovnávat, protože pragma strict mění fundamentální koncept vyhodnocování výrazů, na kterém je založena spousta existujícího kódu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JS 24. 08. 2018, 18:12:17
Knihovna v Haskellu může být napsána úplně skvěle, ale stejně může být pomalá, protože lazy evaluation overhead. No a co teď s tím? Můžu tam dát pragma strict, nebo nemůžu...?
Pragma strict je prilis tezkopadny nastroj na tuhle ulohu. Uz jsem ti prece odkazoval clanky, kde se explicitne popisuje, jak si muzes zavest striktni vyhodnocovani na urovni jednotlivych datovych typu, na urovni jednotlivych predavanych parametru a konecne zcela explicitne primo v kodu pomoci primitivy "seq".

Citace
Já nevím, mně to přijde celé ujeté. Haskell přišel s nějakým designových rozhodnotím (lazy evaluation), což má nějaké výhody a nevýhody. Během doby se přišlo na to, že lazy evaluation stojí docela dost výkonu, tak se hledalo, jak z toho ven.
Ujete to asi je.. ale takhle vznikaji vsechny nove vlastnosti programovacich jazyku. Nove abstrakce nikdy nemaji podporu kompilatoru a temer vzdy znamenaji snizeni vykonu, protoze se setri cas programatorum. Ale eventualne se to (pokud je to dobra vec) do kompilatoru nejak prosadi (nekdo to ten kompilator nakonec nauci) a situace se vyrovna.

Pro priklad muze poslouzit i C++. Pokud si dobre vzpominam, jeste koncem 90. let nebyly kompilatory prilis zdatne v efektivni kompilaci C++ vyjimek. Vety ktere pises vys by tak bylo mozne (tehdy) napsat uplne stejne o vyjimkach.

Citace
Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci.
Omlouvat se nemusis, nikdo te nenuti v nem programovat (aspon doufam :))). Tazatel se ptal, proc je to potencialne rychlejsi (nebo proc se to tvrdi) a ja mu odpovedel.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 18:42:29
Pragma strict je prilis tezkopadny nastroj na tuhle ulohu. Uz jsem ti prece odkazoval clanky, kde se explicitne popisuje, jak si muzes zavest striktni vyhodnocovani na urovni jednotlivych datovych typu, na urovni jednotlivych predavanych parametru a konecne zcela explicitne primo v kodu pomoci primitivy "seq".
seq a podobné opičárny jsou zase jenom narovnávák na ohýbák a v mnoha případech to nefunguje podle očekávání: https://stackoverflow.com/questions/12617664/a-simple-example-showing-that-io-doesnt-satisfy-the-monad-laws/12620418#12620418. Zavést strict do lazy jazyka prostě asi nejde udělat bez hnusných hacků, bohužel pro Haskell...

Omlouvat se nemusis, nikdo te nenuti v nem programovat (aspon doufam :))). Tazatel se ptal, proc je to potencialne rychlejsi (nebo proc se to tvrdi) a ja mu odpovedel.
Tak já mu taky odpovím. Haskell je potenciálně pomalejší, protože má lazy evaluation. Obcházení lazy evaluation zavádí do Haskellu prasárny.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 24. 08. 2018, 18:59:49
Haskell je potenciálně pomalejší, protože má lazy evaluation
To je jen vaření z vody.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 24. 08. 2018, 19:05:27
Haskell je potenciálně pomalejší, protože má lazy evaluation
To je jen vaření z vody.
Jistěže není, lazy evaluation má vyšší overhead než strict evaluation, to je známá věc. Proč myslíš, že do Haskellu zavádí všechny ty strict opičárny, které rozbíjí základní koncepty jazyka? Jediný důvod je výkon.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 19:53:50
No a o tom to celé je. Protože je Haskell lazy, píše se v něm kód, který funguje jen při lazy vyhodnocení a při strict ne. Na to není nic špatného. Jenom je potřeba počítat s tím, že lazy vyhodnocení má z principu vyšší overhead. To se vědělo od začátku. Pak ale někomu začalo vadit, že je Haskell moc pomalý a přemýšlel, jak ho zrychlit. Tak třeba bychom mohli udělat Haskell trochu strict... Co na tom, že rozbijeme existující kód... Mně se Haskell líbí, ale věci jako pragma strict jdou proti jeho designové čistotě a po pravdě moc nechápu, jak někdo z Haskell komunity může takovou věc obhajovat ;).
Protože se lidi z Haskellu snaží být praktičtí a vzhledem k tomu, že strictness analýza prostě dneska není na úrovni toho, kde bude za 20 let, tak prostě zavedli seq? To je snad dobře, ne?

Citace
Chápu důvody vzniku, nepřenesu se ale přes fakt, že to jde proti designu a filozofii jazyka, jen kvůli řešení výkonnostních problémů.
Já tě vůbec nechápu... tady někdo vyrobí jazyk, na kterém se v podstatě testuje spousta nových ideí, které posledních 5 let přejímá spousta dalších mainstream jazyků, zároveň ho udělá tak, že je _použitelný_ na normální produkční programování - sice nemáme geniální strictness analýzu, ale tak když programátor pomůže, tak to bude rozumné - a ty se nemůžeš přenést přes to, že to není "filosoficky čisté"? WTF?

Citace
Sorry jako, takhle podle mě nevypadá mainstreamový jazyk vhodný pro produkční nasazení, ve kterém bych se odvážil psát nějakou větší aplikaci
Já bych se osobně dneska neodvážil psát nějakou větší aplikaci v jazycích, které nemají typový systém aspoň na nějaké podúrovni Haskellu. Nullpointer exception? Stack overflow? Padnuté přetypování? Spousta nechycených výjimek, protože jiné způsoby práce s chybami nejsou použitelné?

Hele, že tys v haskellu ještě nic pořádně nenapsal, nejde ti to, tak jsi se rozhodl, že to "prostě nejde"? Protože věc typu "foldl" je něco, na co narazíš, ale asi tak jednou za projekt, a to ještě . Takže jestli kvůli *tomuhle* ti připadá, že to není jazyk vhodný na produkci, tak jsi asi tak na té úrovni, že C-like jazyky nejsou vhodné do produkce kvůli tomu, že to používá pointry, o kterých sis právě něco přečet a přijde ti to hrozný? Někam vrazíš null, pak to dereferencuješ...a ono to spadne! Jak někdo něco takového může používat v produkci... A pak v tom C pár let programuješ, pointry se naučíš, občas ti to spadne, ale dá se s tím v pohodě žít...?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 24. 08. 2018, 20:00:05
Haskell je potenciálně pomalejší, protože má lazy evaluation
To je jen vaření z vody.
Jistěže není, lazy evaluation má vyšší overhead než strict evaluation, to je známá věc. Proč myslíš, že do Haskellu zavádí všechny ty strict opičárny, které rozbíjí základní koncepty jazyka? Jediný důvod je výkon.
Naprosto. Až budeme mít geniální strictness analýzu a optimalizátory, tak to nebude potřeba.

Ale podobné "prasárny" z jiných jazyků - unboxed values v Javě (int, double, float, short...). Používání objektů na stacku v C++, opičárny s dereferencema a příšerný pravidla, aby se zbytečně nealokovaly/nekopírovaly objekty (kdo TOHLE vymyslel...?). Pointer aritmetika v C. Různé bytearray/buffer apod. v pythonu.

Jasně, tohle nejde proti "čistotě filosofie", protože tyhle jazyky žádnou filosofii nemaj...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 24. 08. 2018, 22:52:17
No a o tom to celé je. Protože je Haskell lazy, píše se v něm kód, který funguje jen při lazy vyhodnocení a při strict ne. Na to není nic špatného. Jenom je potřeba počítat s tím, že lazy vyhodnocení má z principu vyšší overhead. To se vědělo od začátku. Pak ale někomu začalo vadit, že je Haskell moc pomalý a přemýšlel, jak ho zrychlit. Tak třeba bychom mohli udělat Haskell trochu strict... Co na tom, že rozbijeme existující kód... Mně se Haskell líbí, ale věci jako pragma strict jdou proti jeho designové čistotě a po pravdě moc nechápu, jak někdo z Haskell komunity může takovou věc obhajovat ;). Chápu důvody vzniku, nepřenesu se ale přes fakt, že to jde proti designu a filozofii jazyka, jen kvůli řešení výkonnostních problémů.

Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Kiwi 24. 08. 2018, 23:21:41
Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Nechápu, odkud se šíří ty mantry o dokonalosti kompilátorů. Navíc je přebírají a dále šíří lidé, kteří o tom zjevně moc nevědí. Z titulu svého zaměření se na pomezí asm a něčeho lehce vyššího pohybuji, často zkoumám listingy a mohu vás ubezpečit, že i céčkový kompilátor má k dokonalému kódu poměrně daleko. Tím méně bych si dělal iluze u spíše deklarativních jazyků - tam je třeba identifikovat poměrně složité vzorce na vysoké úrovni, což je komplikované. Příkladem nechť je třeba HDL, kde simulaci píšete nějak, ale model pro účely generování zapojení úplně jinak - musíte ten syntezátor doslova dokopat k tomu, co chcete. Jinak sice taky dokáže vygenerovat něco, co něco dělá, ale je to asi tak o řád složitější, pomalejší, náročnější na prostředky. Nevím, jak je tomu dnes, ale jak jsem dával za příklad ten quicksort, který v Haskellu sice vypadá náramně jednoduše, akorát je prakticky k ničemu, protože mu nebude stačit paměť.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 24. 08. 2018, 23:46:13
Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Nechápu, odkud se šíří ty mantry o dokonalosti kompilátorů. Navíc je přebírají a dále šíří lidé, kteří o tom zjevně moc nevědí. Z titulu svého zaměření se na pomezí asm a něčeho lehce vyššího pohybuji, často zkoumám listingy a mohu vás ubezpečit, že i céčkový kompilátor má k dokonalému kódu poměrně daleko. Tím méně bych si dělal iluze u spíše deklarativních jazyků - tam je třeba identifikovat poměrně složité vzorce na vysoké úrovni, což je komplikované. Příkladem nechť je třeba HDL, kde simulaci píšete nějak, ale model pro účely generování zapojení úplně jinak - musíte ten syntezátor doslova dokopat k tomu, co chcete. Jinak sice taky dokáže vygenerovat něco, co něco dělá, ale je to asi tak o řád složitější, pomalejší, náročnější na prostředky. Nevím, jak je tomu dnes, ale jak jsem dával za příklad ten quicksort, který v Haskellu sice vypadá náramně jednoduše, akorát je prakticky k ničemu, protože mu nebude stačit paměť.
Nejde vždy jen o překlad, největší vliv na efektivitu mají optimalizované datové struktury. V případě indexovatelného nebo asociativního pole je například funkcionální implementace stejně efektivní jako mutabilní díky optimalizacím uniqref a cow. Třeba ten quicksort tak prakticky běží in situ, i když sémantiku si zachová funkcionální.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: optimizer 25. 08. 2018, 00:05:44
Třeba ten quicksort tak prakticky běží in situ, i když sémantiku si zachová funkcionální.

LOL
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: hawran diskuse 25. 08. 2018, 00:33:41
No pěkně.
Także co se mi bude psát lépe, gui (pro něco) v c++, nebo v haskellu?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 25. 08. 2018, 00:39:04
No pěkně.
Także co se mi bude psát lépe, gui (pro něco) v c++, nebo v haskellu?
V Haskellu se teď na GUI docela rozjíždí FRP. Bohužel osobně s tím mám zkušenosti pár let staré (což bylo v podstatě v plenkách), nicméně co jsem četl, tak s tím jsou lidé docela spokojeni. On je spíš problém v těch GUI knihovnách. Daří se to implementovat jako webové UI, ale překlad Haskell -> JS je trochu uhozená záložitost. Očekává se, že příchod WebAssembly by tuhle část mohl (a to nejen pro haskell, ale i pro další jazyky) výrazně posunout vpřed.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 25. 08. 2018, 01:36:40
Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Z titulu svého zaměření se na pomezí asm a něčeho lehce vyššího pohybuji, často zkoumám listingy a mohu vás ubezpečit, že i céčkový kompilátor má k dokonalému kódu poměrně daleko.
Z titulu svého zaměření tě můžu ubezpečit, že věci, které dokáže vyplodit 80procent vývojářů... by tě chytl infarkt.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Kiwi 25. 08. 2018, 09:52:52
Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Z titulu svého zaměření se na pomezí asm a něčeho lehce vyššího pohybuji, často zkoumám listingy a mohu vás ubezpečit, že i céčkový kompilátor má k dokonalému kódu poměrně daleko.
Z titulu svého zaměření tě můžu ubezpečit, že věci, které dokáže vyplodit 80procent vývojářů... by tě chytl infarkt.
To rozhodně.  :D Ale mám obavy, že co není v hlavě, to kompilátor nespraví, ale u imperativních jazyků vynásobí, u funkcionálních spíš umocní. Proto ten současný funkcionální hype nesdílím, protože mám obavy, že jakmile by se to paradigma rozšířilo více do praxe, tak budeš mezi prvními, koho pak s tím infarktem doopravdy povezou.  ;)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 25. 08. 2018, 11:56:14
Hmm, takže pokud tě chápu dobře, tak tobě nevadí, že je Haskell lazy, či strict ale to, že vůbec má nějaké pragmy? Tak s tím bych se i stotožnil. Do optimalizace kódu by programátor kompilátoru neměl kecat. (Připomíná mi to hinty v Oracle či Postgresu.)
Z titulu svého zaměření se na pomezí asm a něčeho lehce vyššího pohybuji, často zkoumám listingy a mohu vás ubezpečit, že i céčkový kompilátor má k dokonalému kódu poměrně daleko.
Z titulu svého zaměření tě můžu ubezpečit, že věci, které dokáže vyplodit 80procent vývojářů... by tě chytl infarkt.
Proto ten současný funkcionální hype nesdílím, protože mám obavy, že jakmile by se to paradigma rozšířilo více do praxe, tak budeš mezi prvními, koho pak s tím infarktem doopravdy povezou.  ;)
Takže Haskell v korporátu nehrozí?  :D
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: hawran diskuse 25. 08. 2018, 11:57:29
... ale překlad Haskell -> JS ...
Jakože javashit?
Aháááá.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 25. 08. 2018, 12:46:52
No pěkně.
Także co se mi bude psát lépe, gui (pro něco) v c++, nebo v haskellu?
příchod WebAssembly by tuhle část mohl (a to nejen pro haskell, ale i pro další jazyky) výrazně posunout vpřed.
WebAssembly je hodně zajímavá věc, ale než se to rozšíří...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 25. 08. 2018, 19:51:21
Ale mám obavy, že co není v hlavě, to kompilátor nespraví, ale u imperativních jazyků vynásobí, u funkcionálních spíš umocní. Proto ten současný funkcionální hype nesdílím, protože mám obavy, že jakmile by se to paradigma rozšířilo více do praxe, tak budeš mezi prvními, koho pak s tím infarktem doopravdy povezou.  ;)

Mě se to nezdá.

Základním problémem imperativního programování je OOP. Vyžaduje příliš velký skill, aby se dal psát dobře. U FP skutečnost, že všechno je funkce, která nejde moc rozkošatit, tak to IMHO hodně sváže ruce kreativitě některých vývojářů.

Teda, moje úvaha je taková, že u FP jde vždycky špatný kód wrapnout, a postupně odlifrovat do zapomění. Zatímco u OOP se ty špagety někdy opravdu těško rozmotávají.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: uetoyo 25. 08. 2018, 21:40:27
Ale mám obavy, že co není v hlavě, to kompilátor nespraví, ale u imperativních jazyků vynásobí, u funkcionálních spíš umocní. Proto ten současný funkcionální hype nesdílím, protože mám obavy, že jakmile by se to paradigma rozšířilo více do praxe, tak budeš mezi prvními, koho pak s tím infarktem doopravdy povezou.  ;)

Mě se to nezdá.

Základním problémem imperativního programování je OOP. Vyžaduje příliš velký skill, aby se dal psát dobře. U FP skutečnost, že všechno je funkce, která nejde moc rozkošatit, tak to IMHO hodně sváže ruce kreativitě některých vývojářů.

Teda, moje úvaha je taková, že u FP jde vždycky špatný kód wrapnout, a postupně odlifrovat do zapomění. Zatímco u OOP se ty špagety někdy opravdu těško rozmotávají.

Mě se to nezdá.

Základním problémem OOP programování je imperativnost.

Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 25. 08. 2018, 22:53:56
Základním problémem OOP programování je imperativnost.
Jo.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 25. 08. 2018, 23:09:55
Základním problémem OOP programování je imperativnost.
Jo.
To si pak člověk nevybere, každé paradigma má problematické aspekty.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 26. 08. 2018, 04:59:53
Protože se lidi z Haskellu snaží být praktičtí a vzhledem k tomu, že strictness analýza prostě dneska není na úrovni toho, kde bude za 20 let, tak prostě zavedli seq? To je snad dobře, ne?
Není to dobře, protože to rozbíjí základní koncepty jazyka. Něco ke čtení:
https://www.orchid.inf.tu-dresden.de/gdp/reports/p76-voigtlaender.pdf
https://stackoverflow.com/questions/12617664/a-simple-example-showing-that-io-doesnt-satisfy-the-monad-laws/12620418#12620418
https://wiki.haskell.org/Performance/Strictness#Evaluating_expressions_strictly
Warning: Using any kind of strictness annotations as above can have unexpected impact on program semantics, in particular when certain optimizations are performed by the compiler. See correctness of short cut fusion.

Haskell si tak nějak neumí vybrat, co chce být. Jestli akademický jazyk, který má ukázat, jak se to má dělat správně, nebo jazyk, který bude i pro mainstreamované použití. Chtěli jít i tou druhou cestou, potřebovali vylepšit výkon, tak začali tu akademickou část prasit. Ve výsledku není Haskell ani jedno a výkon taky nic moc.

Já bych se osobně dneska neodvážil psát nějakou větší aplikaci v jazycích, které nemají typový systém aspoň na nějaké podúrovni Haskellu. Nullpointer exception? Stack overflow? Padnuté přetypování? Spousta nechycených výjimek, protože jiné způsoby práce s chybami nejsou použitelné?
Všechno co jsi vyjmenoval umí ošetřit i jiné jazyky. Třeba Rust s výkonem řádově jinde než Haskell.

Hele, že tys v haskellu ještě nic pořádně nenapsal, nejde ti to, tak jsi se rozhodl, že to "prostě nejde"?
S Haskellem jsem si v rámci výzkumu soukromě hrál a nepřesvědčil mě, na větší projekt bych ho nepoužil. Můžeš si klidně myslet, že mi to v Haskellu nejde, je mi to jedno. Důvodů, proč mě Haskell nepřesvědčil, je víc, výkon je až někde hodně vzadu.

C-like jazyky nejsou vhodné do produkce kvůli tomu, že to používá pointry,
Ale to je dávno známá věc, že C-like jazyky nejsou vhodné pro produkci. K používání C v produkci už je dnes jen pár legitimních důvodu: omezené zdroje (RAM, CPU) nebo požadavky na co nejvyšší výkon. V jiném případě se prakticky vždy vyplatí sáhnout po něčem jiném než C.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 26. 08. 2018, 05:09:48
Naprosto. Až budeme mít geniální strictness analýzu a optimalizátory, tak to nebude potřeba.
Až budeme mít růžové slony schopné psát dokonalý kód v assembleru, nebou žádné optimalizátory potřeba.

Ale podobné "prasárny" z jiných jazyků - unboxed values v Javě (int, double, float, short...).
Máš v tom trochu hokej, prasárna je spíš boxování.

Používání objektů na stacku v C++
Tady ses úplně odkopal, objekty na stacku jsou skvělá věc. Jiné jazyky včetně Haskellu se taky snaží co nejvíc objektů alokovat na stacku, používají na to escape analysis (která samozřejmě není dokonalá), v C++ si můžeš explicitně zvolit, jestli objekt vytvoříč na stacku nebo na heapu.

, opičárny s dereferencema a příšerný pravidla, aby se zbytečně nealokovaly/nekopírovaly objekty (kdo TOHLE vymyslel...?). Pointer aritmetika v C. Různé bytearray/buffer apod. v pythonu.

Jasně, tohle nejde proti "čistotě filosofie", protože tyhle jazyky žádnou filosofii nemaj...
Je potřeba podívat se na věci v historickém konceptu. Pointery vznikly kdysi dávno ještě před C, v podstatě už na úrovni strojového kódu. Ví se, že pointery a poiterová aritmetika jsou nebezpečná věc. Většina jazyků se s tím snaží v průběhu času něco dělat a situaci zlepšovat (reference, smart pointery...). V Rustu na raw pointer mimo unsafe kód nenarazíš, v C++ byla docela přelomová verze C++11. Od C++11 raw pointery prakticky nemusíš používat. Vývoj jde tak nějak správnou cestou dopředu. Haskell do dělá opačně, na začátku to udělali správně (lazy evaluation i když s vyšším overheadem), ale pak si řekli: "Je sice moc hezké, ale moc pomalé, trochu to doprasíme. Doděláme strict evaluation.".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 26. 08. 2018, 09:43:26
Naprosto. Až budeme mít geniální strictness analýzu a optimalizátory, tak to nebude potřeba.
Až budeme mít růžové slony schopné psát dokonalý kód v assembleru, nebou žádné optimalizátory potřeba.
Přesně. A do té doby je docela rozumné mít možnost vysvětlit kompilátoru JAK chceš daný kód vykonávat. What's the problem?

Citace
Ale podobné "prasárny" z jiných jazyků - unboxed values v Javě (int, double, float, short...).
Máš v tom trochu hokej, prasárna je spíš boxování.
Aha... jasně. Tak si zkus udělat Nějaké generikum s unboxovaným číslem. Nejde to. Proč? Protože unboxované čísla tam máme z toho důvodu, protože jinak by to bylo tragicky pomalý. Tak trochu to likviduje čistotu jazyka...ale co se dá dělat....
Citace
Používání objektů na stacku v C++
Tady ses úplně odkopal, objekty na stacku jsou skvělá věc. Jiné jazyky včetně Haskellu se taky snaží co nejvíc objektů alokovat na stacku, používají na to escape analysis (která samozřejmě není dokonalá), v C++ si můžeš explicitně zvolit, jestli objekt vytvoříč na stacku nebo na heapu.
Ale ten problém je, že to já jako uživatel musím vůbec řešit. Ty si stěžuješ, že haskellu musíš říct, jestli má použít foldl nebo foldl', a třeba v C++ tohle musíš pořád řešit taky - kde použít smart pointry, různý to opičárny v operátorech, aby se odkazovalo, kde se odkazovat má, nekopírovalo, kde se nekopírovat nemá... a najednou říct překladači, že má použít strict je problém? Máš psa a chceš ho bít?
Citace
, opičárny s dereferencema a příšerný pravidla, aby se zbytečně nealokovaly/nekopírovaly objekty (kdo TOHLE vymyslel...?). Pointer aritmetika v C. Různé bytearray/buffer apod. v pythonu.

Jasně, tohle nejde proti "čistotě filosofie", protože tyhle jazyky žádnou filosofii nemaj...
Je potřeba podívat se na věci v historickém konceptu. Pointery vznikly kdysi dávno ještě před C, v podstatě už na úrovni strojového kódu. Ví se, že pointery a poiterová aritmetika jsou nebezpečná věc. Většina jazyků se s tím snaží v průběhu času něco dělat a situaci zlepšovat (reference, smart pointery...). V Rustu na raw pointer mimo unsafe kód nenarazíš, v C++ byla docela přelomová verze C++11. Od C++11 raw pointery prakticky nemusíš používat. Vývoj jde tak nějak správnou cestou dopředu. Haskell do dělá opačně, na začátku to udělali správně (lazy evaluation i když s vyšším overheadem), ale pak si řekli: "Je sice moc hezké, ale moc pomalé, trochu to doprasíme. Doděláme strict evaluation.".
[/quote]
Je strašně hezké, že máme objekty v Javě, ale je to moc pomalé. Trochu to doprasíme, uděláme unboxed čísla. Je strašně hezké všude dělat kopie v C++, ale trochu to doprasíme, uděláme odkazy..... Ale pokračujme dál: volatile. Různé bariéry v multithreadovaných programech.

Všechny tyhle jazyky ti evidentně umožňují ovlivnit způsob vykonávání kódu - a to jsou založeny na tom, že to, co napíšeš, se v podstatě přesně vykoná. A i tak v tom málu, kde ten kompiler může improvizovat, ti to umožňují. Haskell je založen na úplně jiných principech, kompiler může improvizovat na mnohem vyšší úrovni - a najednou je "špatně", že můžeš ovlivnit způsob vykonávání kódu? Protože haskell má - na rozdíl od ostatních - "čistou filosofii", a lopata řekla, že by to byl hřích porušit?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 26. 08. 2018, 09:57:21
Protože se lidi z Haskellu snaží být praktičtí a vzhledem k tomu, že strictness analýza prostě dneska není na úrovni toho, kde bude za 20 let, tak prostě zavedli seq? To je snad dobře, ne?
Není to dobře, protože to rozbíjí základní koncepty jazyka. Něco ke čtení:
https://www.orchid.inf.tu-dresden.de/gdp/reports/p76-voigtlaender.pdf
https://stackoverflow.com/questions/12617664/a-simple-example-showing-that-io-doesnt-satisfy-the-monad-laws/12620418#12620418
https://wiki.haskell.org/Performance/Strictness#Evaluating_expressions_strictly

Warning: Using any kind of strictness annotations as above can have unexpected impact on program semantics, in particular when certain optimizations are performed by the compiler. See correctness of short cut fusion.

Haskell si tak nějak neumí vybrat, co chce být. Jestli akademický jazyk, který má ukázat, jak se to má dělat správně, nebo jazyk, který bude i pro mainstreamované použití. Chtěli jít i tou druhou cestou, potřebovali vylepšit výkon, tak začali tu akademickou část prasit. Ve výsledku není Haskell ani jedno a výkon taky nic moc.

Někde je nějaký paper o tom, jak všechno tohle, co linkuješ je akademicky pravda a v praxi irelevantní (teď si fakt nemůžu vzpomenout jak se jmenoval). Konkrétně u "fusion" jde o to, že program, který by jinak spadnul, překvapivě funguje. Což je fakt děsný problém.

Ono by fakt asi bylo lepší, kdyby ta seq nebyl, čímž pádem by foldl nešlo reálně vyhodnotit - ale bylo by to filosoficky čisté a pak bysto rozhodně začal používat??

Nebo kdyby to naopak bylo celé strict, takže bys u spousty knihoven měl 2 verze toho samého, jednou pro strict a jednou pro lazy variantu? (viz knihovny u purescriptu) To by byla taky evidentně výhra...? Nebo jak si to představuješ?

Citace
Já bych se osobně dneska neodvážil psát nějakou větší aplikaci v jazycích, které nemají typový systém aspoň na nějaké podúrovni Haskellu. Nullpointer exception? Stack overflow? Padnuté přetypování? Spousta nechycených výjimek, protože jiné způsoby práce s chybami nejsou použitelné?
Všechno co jsi vyjmenoval umí ošetřit i jiné jazyky. Třeba Rust s výkonem řádově jinde než Haskell.
A výkon je faaakt ta nejdůležitější věc, kteoru si vybírám v jazyce....  Toho psa brzo ubiješ...

Citace
Hele, že tys v haskellu ještě nic pořádně nenapsal, nejde ti to, tak jsi se rozhodl, že to "prostě nejde"?
S Haskellem jsem si v rámci výzkumu soukromě hrál a nepřesvědčil mě, na větší projekt bych ho nepoužil. Můžeš si klidně myslet, že mi to v Haskellu nejde, je mi to jedno. Důvodů, proč mě Haskell nepřesvědčil, je víc, výkon je až někde hodně vzadu.
No vždyť jo, celou dobu tady píšeš, že ti na haskellu vadí, že není filosoficky čistý, nikoliv výkon. Tak právě píšu, že to je dost uhozený důvod jazyk nepoužít...

Citace
C-like jazyky nejsou vhodné do produkce kvůli tomu, že to používá pointry,
Ale to je dávno známá věc, že C-like jazyky nejsou vhodné pro produkci. K používání C v produkci už je dnes jen pár legitimních důvodu: omezené zdroje (RAM, CPU) nebo požadavky na co nejvyšší výkon. V jiném případě se prakticky vždy vyplatí sáhnout po něčem jiném než C.
No vidíš a dlouhou dobu se v produkci používaly.... Co třeba Java s nullpointerexception? Taky se dlouho používala - a používá. Prostě ty kompilery a jazyky nejsou dokonalé...ale fakt, že Haskell není filosoficky čistý je prostě důvod ten jazyk nepoužít.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 26. 08. 2018, 10:42:43
Andy, pořád jsi nepochopil, jaká je strict vyhodnocení v Haskellu prasárna. Nevadí, zkusím to znovu. Změnit způsob vykonávání kódu a změnit sémantiku existujícího kódu jsou totiž dost rozdílné věci. Když píšeš třídu v C++, nemusíš přemýšlet o tom, jestli bude vytvořená na heapu nebo na stacku, bude fungovat v obou případech. Neexistuje žádné pragma stack ani pragma heap, které by měnilo sémantiku kódu ve třídě, podle toho, jestli je vytvořená na stacku nebo heapu. Pragma strict v Haskellu to ale dělá, kód který funguje bez pragma strict nemusí fungovat s ním a naopak. Úlpně to mení sémantiku kódu, nikoliv takové detaily, kde leží data, jestli na stacku nebo na heapu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: borekz 26. 08. 2018, 13:19:46
No vidíš a dlouhou dobu se v produkci používaly.... Co třeba Java s nullpointerexception? Taky se dlouho používala - a používá.
Co je nebezpečného na tom, že Java předvídatelně vyhodí výjimku při dereferencování null pointeru ? C umí akorát SIGSEGV při přístupu na určitý rozsah adres a asi právě proto adresový prostor nezačíná na nule, ale o několik megabytů výše. V případě hodně dlouhého pole začínajícího na nule se to odchytit nemusí. Problém pointerů a v C ale jinde. Snadno se poškodí nesouvisející paměť, v horším případě zásobník a chyba se nemusí projevit ihned na místě chyby v kódu, ale může se projevit se zpožděním naprosto nepředvídatelně a tudíž neodhalitelně.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: hawran diskuse 26. 08. 2018, 14:08:00
No vidíš a dlouhou dobu se v produkci používaly.... Co třeba Java s nullpointerexception? Taky se dlouho používala - a používá.
Co je nebezpečného na tom, že Java předvídatelně vyhodí výjimku při dereferencování null pointeru ? C umí akorát SIGSEGV při přístupu na určitý rozsah adres a asi právě proto adresový prostor nezačíná na nule, ale o několik megabytů výše. V případě hodně dlouhého pole začínajícího na nule se to odchytit nemusí. Problém pointerů a v C ale jinde. Snadno se poškodí nesouvisející paměť, v horším případě zásobník a chyba se nemusí projevit ihned na místě chyby v kódu, ale může se projevit se zpožděním naprosto nepředvídatelně a tudíž neodhalitelně.

Maně si vybavuju, že právě že na nule by neměl začínat žádný paměťový segment namapovaný do adresového prostoru procesu a proto přístup k adrese 0 (která je součástí takové "nenamapované" stránky) způsobí ten segfault.
Jinak samozřejmě když pointer nastavím na jakoukoli hodnotu v existujícím prostoru adres, tak se ten segfault vyhodit nemusí a pak už záleží jen na tom, kam ten pointer ukazuje.
(podařilo se mi to dohledat: https://en.wikipedia.org/wiki/Page_fault#Invalid)

PS: Ale jinak samozřejmě souhlasím s pointou Tvé poznámky.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 26. 08. 2018, 18:07:25
Andy, pořád jsi nepochopil, jaká je strict vyhodnocení v Haskellu prasárna. Nevadí, zkusím to znovu. Změnit způsob vykonávání kódu a změnit sémantiku existujícího kódu jsou totiž dost rozdílné věci. Když píšeš třídu v C++, nemusíš přemýšlet o tom, jestli bude vytvořená na heapu nebo na stacku, bude fungovat v obou případech. Neexistuje žádné pragma stack ani pragma heap, které by měnilo sémantiku kódu ve třídě, podle toho, jestli je vytvořená na stacku nebo heapu. Pragma strict v Haskellu to ale dělá, kód který funguje bez pragma strict nemusí fungovat s ním a naopak.
volatile? V kombinaci s -O0 a -O2? To ti v multithreadovaným programu sakra změní sémantiku kódu.

Citace
Úlpně to mení sémantiku kódu, nikoliv takové detaily, kde leží data, jestli na stacku nebo na heapu.
Úplně..? Jako že ti ta část kódu vrátí JINÝ výsledek? Fakt? Tak to by mě zajímalo, protože pokud vím, tak ta změna je maximálně v tom smyslu, že za určitých dost specifických okolností místo bottom vrátí smysluplný výsledek (fusion) nebo naopak místo výsledku to dá bottom. Tomu říkáš "úplně změní sémantiku kódu"?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 26. 08. 2018, 18:28:35
Já tě stejně nechápu. Označení parametru/části recordu jako strikt samozřejmě mění sémantiku, ale je to asi tak na té úrovni, jako když v C++ použiješ "&". To taky mění sémantiku. A taky se to používá pro rychlost. Strict/StrictData vzniklo, protože pro některé typy úloh je lepší mít všechno strict. Když člověk píše nějaký modul, který v podstatě jenom něco počítá, tak typicky chce všechno strict. Tak tam přidali tuhle pragmu, aby nemusel před každý parametr psát vykřičník. Proto jsou taky tyhle direktivy 2 - StrictData a Strict, přičemž typicky StrictData je bezpečná a Strict poněkud méně. Stejně maximálně tak nějaký kód vrátí bottom...

Pokud ti to připadá nebezpečné, tak ty direktivy prostě nepoužívej a piš si ke každému parametru vykřičník. V čem je problém?
BTW, kompilátory, které pracují s floating point kódem, mají takové milé direktivy typu "-ffast-math" apod., které také mění sémantiku floating point kódu...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 26. 08. 2018, 18:36:50
No vidíš a dlouhou dobu se v produkci používaly.... Co třeba Java s nullpointerexception? Taky se dlouho používala - a používá.
Co je nebezpečného na tom, že Java předvídatelně vyhodí výjimku při dereferencování null pointeru ? C umí akorát SIGSEGV při přístupu na určitý rozsah adres a asi právě proto adresový prostor nezačíná na nule, ale o několik megabytů výše. V případě hodně dlouhého pole začínajícího na nule se to odchytit nemusí. Problém pointerů a v C ale jinde. Snadno se poškodí nesouvisející paměť, v horším případě zásobník a chyba se nemusí projevit ihned na místě chyby v kódu, ale může se projevit se zpožděním naprosto nepředvídatelně a tudíž neodhalitelně.
To, že vůbec něco jako null pointer exception existuje (resp. že na to je poměrně obvykle i při slušném psaní kódu narazit). V Javě jakýkoliv datový typ obsahuje null. V Haskellu ne (obsahuje bottom, ale to je trošku jiná kategorie - ale i to se mnohým nelíbí a chtěli by totality checking). Ten rozdíl je v tom, že pokud člověk programuje v Haskellu (a nepoužívá prasácké funkce), tak žádná null pointer exception nenastane. Obdoba v haskellu by byl nějaký neošetřený pattern match, ale na to kompiler kromě nějakých extrémních situací upozorní. A právě v Javě s tímhle bojovali, takže od toho jsou tam dneska anotace @Nullable, @NonNull, a nebo to třeba pak řeší i Kotlin, kde už jde specifikovat, jestli typ může obsahovat null nebo ne - opět vliv jazyků typu Haskell.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Filip Jirsák 26. 08. 2018, 19:43:06
A právě v Javě s tímhle bojovali, takže od toho jsou tam dneska anotace @Nullable, @NonNull, a nebo to třeba pak řeší i Kotlin, kde už jde specifikovat, jestli typ může obsahovat null nebo ne - opět vliv jazyků typu Haskell.
Jenom doplním, že anotace jako @Nullable nebo @NotNull pocházejí z externích knihoven, samotná Java to od verze 8 řeší třídou Optional. Jsem zvědav, jak se to ujme – na jednu stranu je to ošklivé, na druhou stranu by ta ošklivost mohla vést k tomu, aby se nullable typy používaly jen minimálně, když je to opravdu nevyhnutelné.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 27. 08. 2018, 00:46:15
Andy, pořád jsi nepochopil, jaká je strict vyhodnocení v Haskellu prasárna. Nevadí, zkusím to znovu. Změnit způsob vykonávání kódu a změnit sémantiku existujícího kódu jsou totiž dost rozdílné věci. Když píšeš třídu v C++, nemusíš přemýšlet o tom, jestli bude vytvořená na heapu nebo na stacku, bude fungovat v obou případech. Neexistuje žádné pragma stack ani pragma heap, které by měnilo sémantiku kódu ve třídě, podle toho, jestli je vytvořená na stacku nebo heapu. Pragma strict v Haskellu to ale dělá, kód který funguje bez pragma strict nemusí fungovat s ním a naopak. Úlpně to mení sémantiku kódu, nikoliv takové detaily, kde leží data, jestli na stacku nebo na heapu.
Ehm... To, jestli program zdechne na stack overflow, nebo bude v pohodě pracovat, je zatraceně velký rozdíl v sémantice.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 01:23:15
Andy, pořád jsi nepochopil, jaká je strict vyhodnocení v Haskellu prasárna. Nevadí, zkusím to znovu. Změnit způsob vykonávání kódu a změnit sémantiku existujícího kódu jsou totiž dost rozdílné věci. Když píšeš třídu v C++, nemusíš přemýšlet o tom, jestli bude vytvořená na heapu nebo na stacku, bude fungovat v obou případech. Neexistuje žádné pragma stack ani pragma heap, které by měnilo sémantiku kódu ve třídě, podle toho, jestli je vytvořená na stacku nebo heapu. Pragma strict v Haskellu to ale dělá, kód který funguje bez pragma strict nemusí fungovat s ním a naopak. Úlpně to mení sémantiku kódu, nikoliv takové detaily, kde leží data, jestli na stacku nebo na heapu.
Ehm... To, jestli program zdechne na stack overflow, nebo bude v pohodě pracovat, je zatraceně velký rozdíl v sémantice.
To asi není zrovna způsob, jak definovat sémantiku programu. On jakýkoliv program třeba může zdechnout v důsledku vyčerpání omezené paměti, a to může být závislé na nějakém optimalizačním flagu. Třeba v v C++ při vypnutí určitých optimalizací (rekurzivní funkce, dnešní překladače jsou schopny dělat tail-call optimalizaci).

Pod 'úplně jinou sémantikou' je ve funkcionálních jazycích myšleno, že to vrací něco jiného, nikoliv, že to potřebuje 100x tolik zdrojů. Jinak samozřejmě pokud označím jako strict nějakou bottom větev, která se v lazy případě ignoruje, tak to spadne bez ohledu na zdroje (třeba to nikdy neskončí).

Ale já pořád nerozumím tomu argumentu: co je špatného na existenci přepínače, který změní nějaké chování? To má přece spousta jazyků (strict režim JS..?). Nebo je špatně vůbec existence seq? Proč? Protože je špatné, když se dá jazyku říct, jak má co vykonávat? (třeba volatile)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 12:19:45
volatile? V kombinaci s -O0 a -O2? To ti v multithreadovaným programu sakra změní sémantiku kódu.
Volatile nemá s multithreadingem nic společného, nedá se používat jako sychronizační primitivum. Použití volatile na sychronizaci v multithreading prostředí je prakticky vždy chyba. Neřeší to memory bariéry apod. Volatile pouze říká, že překladač nesmí na proměnné provádět optimalizace a musí ji vždy přečíst nebo zapsat z/do paměti. Pokud na takovém chování zavisíš a volatile nepoužiješ, tak je to vždy chyba nezávisle na úrovni optimalizace.

Úplně..? Jako že ti ta část kódu vrátí JINÝ výsledek? Fakt? Tak to by mě zajímalo, protože pokud vím, tak ta změna je maximálně v tom smyslu, že za určitých dost specifických okolností místo bottom vrátí smysluplný výsledek (fusion) nebo naopak místo výsledku to dá bottom. Tomu říkáš "úplně změní sémantiku kódu"?
Jako fakt to může dávat úplně jiné výsledky:
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main =
  do
    let a = myDiv 1 2
    let b = myDiv 1 0
    print a
Kód: [Vybrat]
ghc -O2 test.hs
./test
0.5
ghc -O2 -XStrict test.hs
./test
test: Division by zero
CallStack (from HasCallStack):
  error, called at test.hs:2:13 in main:Main
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 13:24:04
volatile? V kombinaci s -O0 a -O2? To ti v multithreadovaným programu sakra změní sémantiku kódu.
Volatile nemá s multithreadingem nic společného, nedá se používat jako sychronizační primitivum. Použití volatile na sychronizaci v multithreading prostředí je prakticky vždy chyba. Neřeší to memory bariéry apod. Volatile pouze říká, že překladač nesmí na proměnné provádět optimalizace a musí ji vždy přečíst nebo zapsat z/do paměti. Pokud na takovém chování zavisíš a volatile nepoužiješ, tak je to vždy chyba nezávisle na úrovni optimalizace.
Jistě - a program se pak chová jinak podle toho, který flag tomu dáš. Fajn, můžeš říct, že to je prostě blbě (a dle specifikaci asi celkem je). A co ta -ffast-math? Mění sémantiku práce s floating point operacema. Takže máš korektní kód, který se parametrem stane nekorektní..ale rychlejší. Taky problém?

Co 'use strict' v JS? V Perlu je myslím něco podobného.

Citace
Jako fakt to může dávat úplně jiné výsledky:
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main =
  do
    let a = myDiv 1 2
    let b = myDiv 1 0
    print a
Kód: [Vybrat]
ghc -O2 test.hs
./test
0.5
ghc -O2 -XStrict test.hs
./test
test: Division by zero
CallStack (from HasCallStack):
  error, called at test.hs:2:13 in main:Main
Zajímavé, mě přišlo, že v jednom případě main vrátilo (), ve druhém bottom. Všechny funkce vrátily totéž nebo bottom. Máš na to jiný názor?  Jinak to, že v IO jsi schopen detekovat kompilační flagy je celkem pochopitelné. Ale tomu asi neříkáme, že to mění sémantiku programu...?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 15:23:23
A co ta -ffast-math? Mění sémantiku práce s floating point operacema. Takže máš korektní kód, který se parametrem stane nekorektní..ale rychlejší. Taky problém?
Ano -ffast-math je taky prasárna, ne tak velká jako strict v Haskellu, ale pořád prasárna. Aby bylo jasno, já neobhajuju prasárny v jiných jazycích, jsou tam taky. Jenom tvrdím, že -XStrict v Haskellu je prasárna a docela velká. Ty tvrdíš, že -XStrict v Haskellu nevadí, protože ostatní jazyky jsou prasácké taky. Ano jsou, ale to přece není důvod zavádět prasárny i do Haskellu?

Zajímavé, mě přišlo, že v jednom případě main vrátilo (), ve druhém bottom. Všechny funkce vrátily totéž nebo bottom. Máš na to jiný názor?  Jinak to, že v IO jsi schopen detekovat kompilační flagy je celkem pochopitelné. Ale tomu asi neříkáme, že to mění sémantiku programu...?
Mě jako uživatele zajímá, jestli dostanu správný výsledek, nebo ne. Program bez -XStrict pracuje správně (protože závisí na lazy evaluation) a s -XStrict dostanu chybný výsledek. V tom programu přitom žádná chyba není, jen závisí na lazy evaluation a -XStrict ten program rozbije. -XStrict prostě úplně mění sémantiku vyhodnocování a může to korektní program rozbít. Můžeš klidně tvrdit, že main v jednom případě vrátilo () a ve druhém bottom, ale já jako uživatel chci, aby to vracelo správné výsledky stále, ne jenom v jednom případě.

A ještě jedna věc, vem si typickou lopatu, třeba mě, která by chtěla něco dělat v Haskellu. Mám problém, jsem lepič, nějaké řešení najdu na stackoverflow. Mám další problém, další řešení najdu na stackoverflow. Slepím to dohromady. A jsem úplně v háji protože nevím, která část kódu závisí na strict vyhodnocování a která ne. Musím tu informaci někde dohledávat a případně slepený kód pochopit a upravit, na správná místa přidat bang nebo lazy patterny, aby to fungovalo. Když to neudělám, tak se to přeloží, ale v určitých případech se to nemusí chovat správně. Tohle je úplně mimo možnosti běžné lopaty. S -ffast-math lopata mít problém nebude, prostě to přeloží bez -ffast-math a všechno bude fungovat, i když třeba pomaleji. Mimo jiné taky proto zůstane Haskell navždy akademickým jazykem a nestane se mainstreamem. Složitost v kombinaci se strict prasárnami ten jazyk dělá pro běžnou lopatu prakticky nepoužitelným. Bohužel, já mám Haskell rád a líbilo by se mi, kdyby se dal v mainstreamu používat, ale prakticky to zatím nevypadá na úspěch Haskellu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 27. 08. 2018, 15:32:45
Úplně..? Jako že ti ta část kódu vrátí JINÝ výsledek? Fakt? Tak to by mě zajímalo, protože pokud vím, tak ta změna je maximálně v tom smyslu, že za určitých dost specifických okolností místo bottom vrátí smysluplný výsledek (fusion) nebo naopak místo výsledku to dá bottom. Tomu říkáš "úplně změní sémantiku kódu"?
Jako fakt to může dávat úplně jiné výsledky:
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main =
  do
    let a = myDiv 1 2
    let b = myDiv 1 0
    print a
Kód: [Vybrat]
ghc -O2 test.hs
./test
0.5
ghc -O2 -XStrict test.hs
./test
test: Division by zero
CallStack (from HasCallStack):
  error, called at test.hs:2:13 in main:Main
A nějaký prakticky zajímavý příklad by nebyl? Vyhodit nepoužitý blok kódu občas umí optimalizující překladače i ve strict jazycích. Jo, teoreticky je to změna sémantiky. Ale fakt mě nenapadá příklad, kdy by mi tahle změna sémantiky vadila při reálné práci.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 15:51:34
A nějaký prakticky zajímavý příklad by nebyl? Vyhodit nepoužitý blok kódu občas umí optimalizující překladače i ve strict jazycích. Jo, teoreticky je to změna sémantiky.
Pokud má něco side effecty, tak to optimalizující překladač ve strict jazyce vyhodit nesmí a neudělá to (kromě přesně specifikovaných případů ve standardu jako třeba copy elision).

Ale fakt mě nenapadá příklad, kdy by mi tahle změna sémantiky vadila při reálné práci.
Nemáš moc velkou fantazii. Zkus se inspirovat třeba tady: https://www.reddit.com/r/haskell/comments/3sts2t/strict_haskell_xstrict_has_landed/
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 16:25:35
A co ta -ffast-math? Mění sémantiku práce s floating point operacema. Takže máš korektní kód, který se parametrem stane nekorektní..ale rychlejší. Taky problém?
Ano -ffast-math je taky prasárna, ne tak velká jako strict v Haskellu, ale pořád prasárna. Aby bylo jasno, já neobhajuju prasárny v jiných jazycích, jsou tam taky. Jenom tvrdím, že -XStrict v Haskellu je prasárna a docela velká. Ty tvrdíš, že -XStrict v Haskellu nevadí, protože ostatní jazyky jsou prasácké taky. Ano jsou, ale to přece není důvod zavádět prasárny i do Haskellu?
Já nechápu tvoji logiku. Tvrdíš, že když -XStrict vyhodíš, tak se z Haskellu rázem stane skvělý jazyk?


Zajímavé, mě přišlo, že v jednom případě main vrátilo (), ve druhém bottom. Všechny funkce vrátily totéž nebo bottom. Máš na to jiný názor?  Jinak to, že v IO jsi schopen detekovat kompilační flagy je celkem pochopitelné. Ale tomu asi neříkáme, že to mění sémantiku programu...?
Mě jako uživatele zajímá, jestli dostanu správný výsledek, nebo ne. Program bez -XStrict pracuje správně (protože závisí na lazy evaluation) a s -XStrict dostanu chybný výsledek. V tom programu přitom žádná chyba není, jen závisí na lazy evaluation a -XStrict ten program rozbije. -XStrict prostě úplně mění sémantiku vyhodnocování a může to korektní program rozbít. Můžeš klidně tvrdit, že main v jednom případě vrátilo () a ve druhém bottom, ale já jako uživatel chci, aby to vracelo správné výsledky stále, ne jenom v jednom případě.
[/quote]
Takže na to, abys obhájil svůj názor, musíš argumentovat z pozice BFU. Já si nemyslím, že jsi BFU, ale všimni si, kam až musíš klesnout, abys ten názor obhjájil.... Haskell není pro BFU, to máš naprostou pravdu.
Ano, -XStrict mění způsob vyhodnocování a může to konkrétní program rozbít. A co? Tak to tam nepiš a nerozbije ti to.

Citace
A ještě jedna věc, vem si typickou lopatu, třeba mě, která by chtěla něco dělat v Haskellu. Mám problém, jsem lepič, nějaké řešení najdu na stackoverflow. Mám další problém, další řešení najdu na stackoverflow. Slepím to dohromady. A jsem úplně v háji protože nevím, která část kódu závisí na strict vyhodnocování a která ne. Musím tu informaci někde dohledávat a případně slepený kód pochopit a upravit, na správná místa přidat bang nebo lazy patterny, aby to fungovalo.
Dělám s Haskellem možná tak 5 let a na tohle jsem ještě nenarazil. Ono totiž asi tak 99% kódu se chová ve strict a lazy úplně stejně, akorát se to někdy liší ve výkonu (a někdy ani to ne, když to strictness analýza chytí.)

Citace
Složitost v kombinaci se strict prasárnami ten jazyk dělá pro běžnou lopatu prakticky nepoužitelným. Bohužel, já mám Haskell rád a líbilo by se mi, kdyby se dal v mainstreamu používat, ale prakticky to zatím nevypadá na úspěch Haskellu.
Když odstraní -XStrict, tak to tvůj názor změní? Oni to zavedli, protože se některým programátorům nechtělo všude psát '!'. Ale je vidět, že pro některé pouhá existence takového flagu je důvod poslat celý jazyk do háje....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 16:31:48
Ale fakt mě nenapadá příklad, kdy by mi tahle změna sémantiky vadila při reálné práci.
Nemáš moc velkou fantazii. Zkus se inspirovat třeba tady: https://www.reddit.com/r/haskell/comments/3sts2t/strict_haskell_xstrict_has_landed/
No při reálné práci člověk -XStrict nepoužije, pokud nepíše striktní kód. A když píše v haskellu striktní kód, tak asi ví, co dělá....prostě kód, který by ti v jiných jazycích spadnul, ti najednou spadne i v Haskellu, zatímco předtím by třeba kvůli laziness fungoval. Když použiješ -XStrict u kterýho víš, že přesně tenhle efekt mít bude...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 16:36:17
Bohužel, já mám Haskell rád a líbilo by se mi, kdyby se dal v mainstreamu používat, ale prakticky to zatím nevypadá na úspěch Haskellu.
Já ten pocit vůbec nemám, naopak - díky existenci velmi slušných knihoven pro práci s web aplikacemi mám pocit, že se v haskellu píše víc a víc věcí a naopak se začíná docela slušně prosazovat. A rozhodně rozšíření nezpomaluje to, že do 8.0 prosadil někdo, kdo potřeboval často psát strikt kód, pragmu -XStrict....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 27. 08. 2018, 17:31:58
A ještě jedna věc, vem si typickou lopatu, třeba mě, která by chtěla něco dělat v Haskellu. Mám problém, jsem lepič, nějaké řešení najdu na stackoverflow. Mám další problém, další řešení najdu na stackoverflow. Slepím to dohromady. A jsem úplně v háji protože nevím, která část kódu závisí na strict vyhodnocování a která ne. Musím tu informaci někde dohledávat a případně slepený kód pochopit a upravit, na správná místa přidat bang nebo lazy patterny, aby to fungovalo. Když to neudělám, tak se to přeloží, ale v určitých případech se to nemusí chovat správně. Tohle je úplně mimo možnosti běžné lopaty.

Pokud to poslepuješ z "fungujících kousků kódu", tak se dostaneme na úroveň tohoto:

S -ffast-math lopata mít problém nebude, prostě to přeloží bez -ffast-math a všechno bude fungovat, i když třeba pomaleji. (...)

čili, bude to fungovat vždy, jen bude případně problém s výkonem. (pragma bude mít jen ten kód, co to potřebuje, protože to při a) lepení budeš vědět - tedy necháš to pouze na onom souboru b) vědět to nebudeš a tím pádem to bude možná akorát tak pomalejší s lazy eval.)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 17:54:08
čili, bude to fungovat vždy, jen bude případně problém s výkonem. (pragma bude mít jen ten kód, co to potřebuje, protože to při a) lepení budeš vědět - tedy necháš to pouze na onom souboru b) vědět to nebudeš a tím pádem to bude možná akorát tak pomalejší s lazy eval.)
Ty jsi nepochopil, jak to funguje. Pokud je kód v Haskellu napsaný s předpokladem lazy evaluation, tak ho strict evaluation může rozbít. Funguje to i naopak. Pokud je kód v Haskellu napsaný s předpokladem strict evaluation, může ho lazy evaluation rozbít. Nebude to jenom pomalejší s lazy/strict evaluation, nemusí to vůbec fungovat. Takže když něco poslepuješ dohromady, máš potenciální problém. Musíš vědět, s jakým předpokladem byl ten kód napsán a upravovat ho bang patterny podle toho, která část závisí na lazy a která na strict a taky podle toho, jestli to překládáš s XStrict, nebo ne.

Dále bych se k tomu už asi nevyjadřoval, myslím že bylo vše podstatné řečeno a točíme se v kruhu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 19:57:03
Funguje to i naopak. Pokud je kód v Haskellu napsaný s předpokladem strict evaluation, může ho lazy evaluation rozbít. Nebude to jenom pomalejší s lazy/strict evaluation, nemusí to vůbec fungovat.
Ne, bude to jenom pomalejší a může to mít brutálně větší nároky na paměť, ale fungovat to bude. Je to zhruba na stejné úrovni, jako když v C++ napíšeš rekurzivní funkci a spolehneš se na tail call optimalizaci, a pak to někdo přeloží bez optimalizace. Další "nevinný" switch, který "mění sémantiku"..?

 
Citace
Takže když něco poslepuješ dohromady, máš potenciální problém. Musíš vědět, s jakým předpokladem byl ten kód napsán a upravovat ho bang patterny podle toho, která část závisí na lazy a která na strict a taky podle toho, jestli to překládáš s XStrict, nebo ne.
Ano, Haskell není pro lepiče. Nadávání na lepiče, kteří pospojují kousky ze stackoverflow, jak zkompletují kód kterýmu nerozumí a on potom nefunguje je všude dost... ano, haskell pro takové lidi není.

Jinak:

- XStrict prakticky nikdo nepoužívá; to je prostě flag pro pokusy s výpočetními úlohami, je to naprosto okrajové
- Osobně jsem se za 5 let programování v haskellu nesetkal ani jednou se situací, kdy bych něco udělal strict a ono to přestalo fungovat. Popravdě mi připadá, že fakt, že se otáčíš na tomhle je spíš znakem, že jsi v tom neprogramoval, protože ta "změna sémantiky" prostě v praxi problém není. Kromě toho, že v praxi XStrict na "normální" kód prostě nikdo nepoužívá.
- Problém "lazy" evaluace jsou spíš memory leaky - stává se to zřídka. Ale u většího projektu se tak 1-2 povedou a je to strašná otrava to hledat.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 20:25:14
Funguje to i naopak. Pokud je kód v Haskellu napsaný s předpokladem strict evaluation, může ho lazy evaluation rozbít. Nebude to jenom pomalejší s lazy/strict evaluation, nemusí to vůbec fungovat.
Ne, bude to jenom pomalejší a může to mít brutálně větší nároky na paměť, ale fungovat to bude. Je to zhruba na stejné úrovni, jako když v C++ napíšeš rekurzivní funkci a spolehneš se na tail call optimalizaci, a pak to někdo přeloží bez optimalizace. Další "nevinný" switch, který "mění sémantiku"..?
Už opravdu naposledy. Pokud má observable efekty (tím myslím změnu výstupu programu) zapnutí XStrict, je celkem jasné, že observable efekty bude mít i vypnutí XStrict. Za domácí úkol si můžeš zkusit napsat kód, který s XStrict funguje a bez XStrict ne. Není to nic složitého.

Osobně jsem se za 5 let programování v haskellu nesetkal ani jednou se situací, kdy bych něco udělal strict a ono to přestalo fungovat. Popravdě mi připadá, že fakt, že se otáčíš na tomhle je spíš znakem, že jsi v tom neprogramoval, protože ta "změna sémantiky" prostě v praxi problém není. Kromě toho, že v praxi XStrict na "normální" kód prostě nikdo nepoužívá.
Ty v tom programuješ 5 let a stejně nejsi schopen domyslet, jaké důsledky má změna lazy versus strict vyhodnocení, Haskell asi opravdu není pro každého ;). Jen vtip, neber si to osobně.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 20:55:54
Funguje to i naopak. Pokud je kód v Haskellu napsaný s předpokladem strict evaluation, může ho lazy evaluation rozbít. Nebude to jenom pomalejší s lazy/strict evaluation, nemusí to vůbec fungovat.
Ne, bude to jenom pomalejší a může to mít brutálně větší nároky na paměť, ale fungovat to bude. Je to zhruba na stejné úrovni, jako když v C++ napíšeš rekurzivní funkci a spolehneš se na tail call optimalizaci, a pak to někdo přeloží bez optimalizace. Další "nevinný" switch, který "mění sémantiku"..?
Pokud má observable efekty (tím myslím změnu výstupu programu) zapnutí XStrict, je celkem jasné, že observable efekty bude mít i vypnutí XStrict. Za domácí úkol si můžeš zkusit napsat kód, který s XStrict funguje a bez XStrict ne. Není to nic složitého.
Víš, mě připadá, že ses dostal do naprosto absurdní situace z hlediska toho, čím se snažíš tvou tezi obhájit. Začali jsme tím, že část kódu nevrátí jinou hodnotu, maximálně bottom. To jsi musel předefinovat, že lopatě to je jedno, co to vrací, ale že se celý program chová jinak. Ano, lopatě to fakt jedno je, programátor by v tom mohl vidět rozdíl. No, a pak tady je teze, že Lazy->Strict rozbije program, z čehož vůbec nevyplývá, že by Strict->Lazy mohlo rozbít program - no a abys opět dokázal, že máš pravdu, tak pod pojmem "rozbije program" rozumíš "má observable efekt"... Samozřejmě v IO jsi schopen pozorovat "observable efekty" (třeba timing), takže není problém napsat (v jakémkoliv programovacím jazyce) program, který se "rozbije" při jakékoliv změně nějakého flagu....

Jo, "Strict" je trošku drsnější pragma, kterou prakticky nikdo v normálním kódu nepoužívá, ale pro někoho, kdo lepí kód ze stackoverflow to je problém, protože možná někdo v nějaké odpovědi, které nerozumí, zrovna ten "nenormální kód" někdo pastnul...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 27. 08. 2018, 21:57:02
...
Čti co píšu a používej hlavu, nemotej do toho timing a podobné hovadiny: Pokud má observable efekty (tím myslím změnu výstupu programu) zapnutí XStrict, je celkem jasné, že observable efekty bude mít i vypnutí XStrict.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 22:26:07
...
Čti co píšu a používej hlavu, nemotej do toho timing a podobné hovadiny: Pokud má observable efekty (tím myslím změnu výstupu programu) zapnutí XStrict, je celkem jasné, že observable efekty bude mít i vypnutí XStrict.
Chceš snad říct, že tvrdím opak?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 27. 08. 2018, 22:30:49
...
Čti co píšu a používej hlavu, nemotej do toho timing a podobné hovadiny: Pokud má observable efekty (tím myslím změnu výstupu programu) zapnutí XStrict, je celkem jasné, že observable efekty bude mít i vypnutí XStrict.
A napsat program, jehož výstup se mění na základě timingu nějaké funkce je snad nějaký problém, btw?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 27. 08. 2018, 23:14:30
Ty jsi nepochopil, jak to funguje. Pokud je kód v Haskellu napsaný s předpokladem lazy evaluation, tak ho strict evaluation může rozbít. (...)

Tak to bych rád viděl nějaký příklad, ať si doplním znalosti. Za tu dobu, co v Haskellu dělám, jsem na podobný případ nenarazil. :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 05:54:02
Ty jsi nepochopil, jak to funguje. Pokud je kód v Haskellu napsaný s předpokladem lazy evaluation, tak ho strict evaluation může rozbít. (...)

Tak to bych rád viděl nějaký příklad, ať si doplním znalosti. Za tu dobu, co v Haskellu dělám, jsem na podobný případ nenarazil. :)

Opakování je matka moudrosti:
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main =
  do
    let a = myDiv 1 2
    let b = myDiv 1 0
    print a

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
0.5

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
test: Division by zero
CallStack (from HasCallStack):
  error, called at test.hs:2:13 in main:Main

Více pro inspiraci zde: https://www.reddit.com/r/haskell/comments/3sts2t/strict_haskell_xstrict_has_landed/
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 28. 08. 2018, 06:52:25
@lopata: Omlouvám se, špatná citace - měl jsem namysli opačný směr, tj. jak lazy evaluation může rozbít "strict předpokládající" kód. Sorry. :) Na tento případ bys příklad měl?

Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 28. 08. 2018, 07:00:58
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main =
  do
    let a = myDiv 1 2
    let b = myDiv 1 0
    print a

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
0.5

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
test: Division by zero
CallStack (from HasCallStack):
  error, called at test.hs:2:13 in main:Main

imho zrovna v tomto případě bych "čekal", že to optimalizuje kompilátor a onen "vadný řádek" vyhodí (tak jako třeba v C) - zvlášť když zapínáš optimalizace.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 07:20:26
imho zrovna v tomto případě bych "čekal", že to optimalizuje kompilátor a onen "vadný řádek" vyhodí (tak jako třeba v C) - zvlášť když zapínáš optimalizace.
Tak to bys čekal špatně. Kompilátor to NESMÍ vyhodit, protože to má při strict vyhodnocení observable side-effects. Nesmí to vyhodit ani v C ani v Haskellu, v tom není žádný rozdíl.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 28. 08. 2018, 08:07:55
imho zrovna v tomto případě bych "čekal", že to optimalizuje kompilátor a onen "vadný řádek" vyhodí (tak jako třeba v C) - zvlášť když zapínáš optimalizace.
Tak to bys čekal špatně. Kompilátor to NESMÍ vyhodit, protože to má při strict vyhodnocení observable side-effects. Nesmí to vyhodit ani v C ani v Haskellu, v tom není žádný rozdíl.

Kód: [Vybrat]
1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int main(void) {
 5     int x = 9;
 6     int* ptr1 = &x;
 7     int* ptr2 = NULL;
 8
 9      int q = *ptr1;
10     int y = *(ptr2);
11     printf("x: %d\n", q);
12
13     return 0;
14 }
15

Zkus to zkompilovat takto:

Kód: [Vybrat]
gcc -O2 test.c -o test
pak takto:

Kód: [Vybrat]
gcc test.c -o test
a nakonec to modifikuj tak, aby se výraz
Kód: [Vybrat]
*(ptr2) neukládal do proměnné. :)

Btw nejsem si jist, že "observable side-effects" používáš korektně.
Btw2 ten příklad na rozbití "strict" kódu přes lazy evaluation by nebyl? Opravdu mě to zajímá. :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 28. 08. 2018, 08:14:38
@lopata: Omlouvám se, špatná citace - měl jsem namysli opačný směr, tj. jak lazy evaluation může rozbít "strict předpokládající" kód. Sorry. :) Na tento případ bys příklad měl?
Ano, taky na to čekám...
Citace
    Funguje to i naopak. Pokud je kód v Haskellu napsaný s předpokladem strict evaluation, může ho lazy evaluation rozbít. Nebude to jenom pomalejší s lazy/strict evaluation, nemusí to vůbec fungovat.
A za tím jsem se dozvěděl, že "observable side effect" === "rozbít".... Jako ono samozřejmě je možné v IO napsat:

Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Exception (try, SomeException, evaluate)

myConst a b = a
main = do
  res <- try (evaluate (myConst () undefined))
  case res of
    Right () -> error "Je to rozbity"
    Left (_ :: SomeException) -> putStrLn "Funguje to"
Ale to se přesně dostáváme k tomu, že tímhle způsobem umíme "rozbít" kód jakéhokoliv jazyka jakoukoliv optionou překladu, která má "nějaký" vliv, třeba na timing....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 08:30:50
Pánové, observable side effect je terminus technicus: https://en.wikipedia.org/wiki/Side_effect_(computer_science). Pokud neznáte ani takové základní věci, jak se chcete bavit o tom, co může překladač vyhodit a co ne? Normálně se tím myslí:

In computer science, a function or expression is said to have a side effect if it modifies some state outside its local environment, that is to say has an observable interaction with the outside world besides returning a value.

Zjevně v tom máte zmatek. Prakticky zjednodušeně si to můžete představit tak, že observable side effect je něco, co mění výstup programu.

Cikádo, co se týká derefence null pointeru, C standard explicitně říká, že je to UNDEFINED behavior. To znamená, že překladač si s tím může v podstatě udělat co chce. Klidně tu derefenci při optimalizaci vyhodit, protože to stále odpovídá definici undefined behavior. Čekal bych, že takové základní věci budeš znát?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 08:33:46
@lopata: Omlouvám se, špatná citace - měl jsem namysli opačný směr, tj. jak lazy evaluation může rozbít "strict předpokládající" kód. Sorry. :) Na tento případ bys příklad měl?
Ano, taky na to čekám...
Projev taky nějakou vlastní iniciativu. Já jsem ti funkční příklad dal, máš všechny informace potřebné k řešení, opačným směrem to určitě zvládneš taky, když v Haskellu děláš 5 let. Opravdu to není nic složitého, zkus se trochu snažit.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 28. 08. 2018, 08:49:06
@lopata: Omlouvám se, špatná citace - měl jsem namysli opačný směr, tj. jak lazy evaluation může rozbít "strict předpokládající" kód. Sorry. :) Na tento případ bys příklad měl?
Ano, taky na to čekám...
Projev taky nějakou vlastní iniciativu. Já jsem ti funkční příklad dal, máš všechny informace potřebné k řešení, opačným směrem to určitě zvládneš taky, když v Haskellu děláš 5 let. Opravdu to není nic složitého, zkus se trochu snažit.
Vzhledem k tomu, že v haskellu "bottom" je undefined behaviour, a přechod Strict -> Lazy bottom z ničeho nic nevyrobí (protože se toho vyhodnocuje méně), tak si myslím, že to nejde. On už ti to cikáda taky napsal, že si myslí, že to nejde. Maximálně tak můžeš použít příklad, který jsem dal já, což je na té provni undefined behaviour z C.

Takže teď jsme oba důvodně přesvědčeni, že to nejde a ty tady bezdůvodně tvrdíš opak. Tak očekávám, že to podepřeš něčím, čím ukážeš, jak se mýlíme...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 28. 08. 2018, 08:52:49
Pánové, observable side effect je terminus technicus: https://en.wikipedia.org/wiki/Side_effect_(computer_science). Pokud neznáte ani takové základní věci, jak se chcete bavit o tom, co může překladač vyhodit a co ne? Normálně se tím myslí:

In computer science, a function or expression is said to have a side effect if it modifies some state outside its local environment, that is to say has an observable interaction with the outside world besides returning a value.

Zjevně v tom máte zmatek. Prakticky zjednodušeně si to můžete představit tak, že observable side effect je něco, co mění výstup programu.

Toto asi všichni známe, otázkou je, kde je ten side efect. Ta funkce je pure, spadnutí programu není side-efect.

Cikádo, co se týká derefence null pointeru, C standard explicitně říká, že je to UNDEFINED behavior. To znamená, že překladač si s tím může v podstatě udělat co chce. Klidně tu derefenci při optimalizaci vyhodit, protože to stále odpovídá definici undefined behavior. Čekal bych, že takové základní věci budeš znát?

Tak si tam strč to dělení nulou, nebo jinou random adresu. Pointa je jasná.

@lopata: Omlouvám se, špatná citace - měl jsem namysli opačný směr, tj. jak lazy evaluation může rozbít "strict předpokládající" kód. Sorry. :) Na tento případ bys příklad měl?
Ano, taky na to čekám...
Projev taky nějakou vlastní iniciativu. Já jsem ti funkční příklad dal, máš všechny informace potřebné k řešení, opačným směrem to určitě zvládneš taky, když v Haskellu děláš 5 let. Opravdu to není nic složitého, zkus se trochu snažit.

On se blbě vymýšlí příklad, když neexistuje...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 28. 08. 2018, 10:09:55
BTW - příklad na C:
Kód: [Vybrat]
#include <stdio.h>
void func(int i) {
  if (i == 200000000)
     return;
  if (i % 50000000 == 0)
    printf("%d\n", i);
  func(i+1);
}
int main() {
  func(0);
  printf("DONE\n");
}
Kód: [Vybrat]
$ gcc -o a a.c -O2;./a
0
50000000
100000000
150000000
DONE
$ gcc -o a a.c -O0;./a
0
Segmentation fault: 11
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 22:17:21
BTW - příklad na C:
Tak jsi nám ukázal, že stack má omezenou velikost? Jaká je pointa?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 22:21:19
Tak Andy a Cikádo, času jste měli dost, ale nedali jste to. Haskell asi opravdu není pro každého. Dám vám něco k přemýšlení:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main = catch
          (do
               let a = myDiv 1 0
               putStrLn "Předpověď: zítra BUDE krásné počasi"
          )
          (\(err :: SomeException) -> putStrLn "Předpověď: zítra NEBUDE krásné počasi")

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
Předpověď: zítra BUDE krásné počasi

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
Předpověď: zítra NEBUDE krásné počasi
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 28. 08. 2018, 23:01:34
Tak Andy a Cikádo, času jste měli dost, ale nedali jste to. Haskell asi opravdu není pro každého. Dám vám něco k přemýšlení:
Kód: [Vybrat]
myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main = catch
          (do
               let a = myDiv 1 0
               putStrLn "Předpověď: zítra BUDE krásné počasi"
          )
          (\(err :: SomeException) -> putStrLn "Předpověď: zítra NEBUDE krásné počasi")
Ten problém je, že bottom je de-fakto "undefined behaviour". Například kdyby Haskell na "error" zareagoval nekonečnou smyčkou, tak je to vcelku korektní chování překladače. Takže takovýto program přeložený s -XStrict těžko považovat za funkční (úplně stejně, jako ty předchozí příklady v C, kdy jsi oponoval, že je "undefined behaviour"). A nefunkční program asi odstraněním -XStrict nerozbiješ. Takže zkusíš jiný příklad?

Jinak mám pocit, že máš problém se čtením textu, protože o pár postů výše jsem v podstatě identický příklad dal s popisem, proč to nelze považovat za příklad toho, jak přechod Strict->Lazy může rozbít program...

Citace
Tak jsi nám ukázal, že stack má omezenou velikost? Jaká je pointa?
Pointa je, že optimalizační flag v C (a C++ to bude úplně stejně) rozbije program. Protože v tom případě -O2 to nepřeteče nikdy, klidně si tam dej nekonečnou smyčku. Změna optimalizačních flagů v C++ ti naprosto v pohodě rozbije program, aneb - má "observable efekt". To C++ je ale příšerný jazyk, že hraní si s optimalizacema může totálně rozbít program... jak v tom může někdo programovat... :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 28. 08. 2018, 23:02:11
Tak Andy a Cikádo, času jste měli dost, ale nedali jste to. Haskell asi opravdu není pro každého. Dám vám něco k přemýšlení:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

myDiv :: Float -> Float -> Float
myDiv x 0 = error "Division by zero"
myDiv x y = x / y

main = catch
          (do
               let a = myDiv 1 0
               putStrLn "Předpověď: zítra BUDE krásné počasi"
          )
          (\(err :: SomeException) -> putStrLn "Předpověď: zítra NEBUDE krásné počasi")

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
Předpověď: zítra BUDE krásné počasi

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
Předpověď: zítra NEBUDE krásné počasi

Když odhlédneme od toho, že jde o stejný příklad jako předtím, jen místo error používáš výjimky, tak pořád nevidím příklad, kdy lazy evaluation rozbije strict kód. Ale ano, máš pravdu, že Haskell (a programování obecně) není pro každého. :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 23:08:57
Ten problém je, že bottom je de-fakto "undefined behaviour". Například kdyby Haskell na "error" zareagoval nekonečnou smyčkou, tak je to vcelku korektní chování překladače.
Tak moment, tohle budu chtít vysvětlit. Kde je ve standardu Haskellu napsáno, že je něco z mého programu undefined behavior? Kde je ve standardu napsáno, že error může překladač přeložit jako nekonečnou smyčku?

Pointa je, že optimalizační flag v C (a C++ to bude úplně stejně) rozbije program.
Rozbije ho, protože dojde paměť. Kdyby paměť nedošla, bude ten program s optimalizací nebo bez dávat stejný výstup. V Haskellu to s/bez XStrict stejný výstup dát nemusí. To je zásadní rozdíl.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 23:12:00
Když odhlédneme od toho, že jde o stejný příklad jako předtím, jen místo error používáš výjimky, tak pořád nevidím příklad, kdy lazy evaluation rozbije strict kód. Ale ano, máš pravdu, že Haskell (a programování obecně) není pro každého. :)
Používej hlavu. Program nespadne a dává s lazy/strict jiný výstup. To je zásadní problém, pokud očekáváš jedno řešení, minimálně jedna varianta je prostě rozbitá. A pokud chceš tvrdit, že ta strict, tak ti klidně prohodím ty texty, které to píše.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 28. 08. 2018, 23:13:05
FYI ghc a haskell není to samé
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 28. 08. 2018, 23:15:19
hmm překlad C/C++ modulu s "nevhodným" --std=
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 28. 08. 2018, 23:22:29
Ten problém je, že bottom je de-fakto "undefined behaviour". Například kdyby Haskell na "error" zareagoval nekonečnou smyčkou, tak je to vcelku korektní chování překladače.
Tak moment, tohle budu chtít vysvětlit. Kde je ve standardu Haskellu napsáno, že je něco z mého programu undefined behavior? Kde je ve standardu napsáno, že error může překladač přeložit jako nekonečnou smyčku?
To je z computer science - všechny typy v haskellu obsahují bottom, no a error je funkce, která díký free theoremům má výstupní typ pouze bottom:
Citace
A function whose return type is bottom cannot return any value.
Takže ta funkce se prostě nemůže nikdy vrátit. Taky v pure kódu není bottom observable.

Takže v tom kódu výše v podstatě spoléháš na implementační detail v haskellu, že programátoři asi v takovémhle případě nechtějí aby jim to věčně cyklilo, ale chtěli by tuhle rozbitost zachytit a případně udělat nějakou error recovery, takže Haskell v některých případech nezacyklí, ale vyhodí výjimku. Sémanticky je to na té úrovni chytat SIGSEGV.

Proto se taky v Haskellu "error" dneska používá prakticky výhradně ve větvích kódu, které by se stejně nikdy neměly provést a pokud se provedou, jedná se o chybu programu.

Citace
Pointa je, že optimalizační flag v C (a C++ to bude úplně stejně) rozbije program.
Rozbije ho, protože dojde paměť. Kdyby paměť nedošla, bude ten program s optimalizací nebo bez dávat stejný výstup. V Haskellu to s/bez XStrict stejný výstup dát nemusí. To je zásadní rozdíl.
Ne, jsme na tom úplně stejně jako v haskellu - tohleto vyhodnocování je všechno otázka pure kódu a ten to vyhodnotí buď stejně, nebo to dá bottom. No a odchycení bottom je zhruba na stejné úrovni, jako když si uděláš signal handler na SIGSEGV, tu výjimku stack overflow odchytíš a  něco napíšeš na výstup. No a pokud tu rekurzi budeš dělat dostatečně dlouho, tak se dá vcelku garantovat, že ta paměť dojde. Takže ta změna optimalizace má vliv na výstup...

Citace
Používej hlavu. Program nespadne a dává s lazy/strict jiný výstup. To je zásadní problém, pokud očekáváš jedno řešení, minimálně jedna varianta je prostě rozbitá. A pokud chceš tvrdit, že ta strict, tak ti klidně prohodím ty texty, které to píše.
Je rozbitá ta Strict, protože tam dojde k bottom. Když prohodíš ty texty, tak to na tom nic nezmění.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 28. 08. 2018, 23:58:46
To je z computer science - všechny typy v haskellu obsahují bottom, no a error je funkce, která díký free theoremům má výstupní typ pouze bottom:
Jinými slovy říkáš, že error má v podstatě nedefinované chování (i když se může vyskytovat v pure kódu!) a neměl by se používat. Pokud máš pravdu, je docela zarážející, že je to na mnoha místech v Prelude v docela zásadních funkcích:
Kód: [Vybrat]
head             :: [a] -> a
head (x:_)       =  x
head []          =  error "Prelude.head: empty list"
Není to tak trochu nebezpečné? Není to tak trochu prasárna?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 00:41:00
To je z computer science - všechny typy v haskellu obsahují bottom, no a error je funkce, která díký free theoremům má výstupní typ pouze bottom:
Jinými slovy říkáš, že error má v podstatě nedefinované chování (i když se může vyskytovat v pure kódu!) a neměl by se používat.
Přesně tak. V podstatě jediné rozumné použití je pro to říct "tady je chyba kódu". Nikoliv "toto je chyba vstupních dat". Mimochodem, to, co najdeš v snad i v ubčebnicích je, že když pak budeš mít těch errorů víc, tak je zcela nedeterministické, který z nich to nakonec vyhraje.
Tudíž rozumné použití pro "error" je: kód je špatně. Nikoliv "výjimka na základě vstupních dat, ošetříme, zareagujeme".
Citace
Pokud máš pravdu, je docela zarážející, že je to na mnoha místech v Prelude v docela zásadních funkcích:
Kód: [Vybrat]
head             :: [a] -> a
head (x:_)       =  x
head []          =  error "Prelude.head: empty list"
Není to tak trochu nebezpečné? Není to tak trochu prasárna?
Ano, je to nebezpečné, ale z úplně jiných důvodů, než které tu diskutujeme. A je to "historický dluh" ("prasárna"), už  bylo mnohokrát navrhováno, aby se tyhle funkce z Prelude vyhodily, v podstatě jediný důvod, proč tam zůstávají, je, že to je vcelku přístupné pro začátečníky (učební materiály, jednoduchost..Maybe monad fakt není pro první lekci haskellu vhodný). Spousta lidí taky používá custom Prelude, kde tyhle funkce nemají.

Nicméně důvod, proč to chtějí je úplně jiný, než to, co si asi myslíš. Ono je poměrně korektní, aby "head" zavolal "error", když ho zavoláš na prázdný list. Ty ho totiž nemáš co volat na prázdný list, takže máš chybu v kódu - a bottom je korektní výsledek. Prasárna to začne být v momentě, kdy se tu výjimku pokusíš chytit a na základě ní usuzovat něco jiného než "mám tam internal error".

Ten důvod, proč se to z Prelude snaží dostat je ale jiný: je to "partial" funkce. A Haskellisti nemají partial funkce rádi. Boří to motto "if it compiles, it works". Takže ideálně místo toho všichni používají např.:
Kód: [Vybrat]
NonEmpty a = a :| [a]
head :: NonEmpty a -> a
head (a :| _) = a

nebo

safeHead :: [a] -> Maybe a
safeHead (a:_) = Just a
safeHead [] = Nothing
No a pokud head nepoužiješ a použiješ jednu z těchhle variant, tak ti překladač je schopen garantovat, že to na prázdný list nezavoláš.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 01:11:10
Přesně tak. V podstatě jediné rozumné použití je pro to říct "tady je chyba kódu". Nikoliv "toto je chyba vstupních dat". Mimochodem, to, co najdeš v snad i v ubčebnicích je, že když pak budeš mít těch errorů víc, tak je zcela nedeterministické, který z nich to nakonec vyhraje.
Tudíž rozumné použití pro "error" je: kód je špatně. Nikoliv "výjimka na základě vstupních dat, ošetříme, zareagujeme".
Ale to má Haskell udělané úplně blbě. Dokud tam budou takové prasárny (v pure kódu!), nikdy se z něj nestane normálně použitelný jazyk. Byl by problém zadefinovat, co konkrétně má error udělat? Nebyl, ale asi to není dostatečně akademické řešení... Srovnej v panic v Rustu, dělá prakticky to stejné a naprosto definovaně, dá se normálně používat: https://doc.rust-lang.org/std/macro.panic.html
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 01:42:27
Přesně tak. V podstatě jediné rozumné použití je pro to říct "tady je chyba kódu". Nikoliv "toto je chyba vstupních dat". Mimochodem, to, co najdeš v snad i v ubčebnicích je, že když pak budeš mít těch errorů víc, tak je zcela nedeterministické, který z nich to nakonec vyhraje.
Tudíž rozumné použití pro "error" je: kód je špatně. Nikoliv "výjimka na základě vstupních dat, ošetříme, zareagujeme".
Ale to má Haskell udělané úplně blbě. Dokud tam budou takové prasárny (v pure kódu!), nikdy se z něj nestane normálně použitelný jazyk. Byl by problém zadefinovat, co konkrétně má error udělat? Nebyl, ale asi to není dostatečně akademické řešení... Srovnej v panic v Rustu, dělá prakticky to stejné a naprosto definovaně, dá se normálně používat: https://doc.rust-lang.org/std/macro.panic.html
Jaká prasárna v pure kódu? Teď ti vůbec nerozumím. Error je něco jako přístup na nulovou adresu v C. Tam je taky zadefinované (na OS s MMU), že to vygeneruje SIGSEGV. Akorát ten error se dá potom v IO chytit. Proč bys proboha něco takového chtěl "normálně" používat? To je funkce, která vůbec není určená pro "normální" použití. Nebo snad normálně používáš přístup na nulovou adresu a chytání SIGSEGV jako "normální" ošetření chyb?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 02:00:51
Jaká prasárna v pure kódu? Teď ti vůbec nerozumím. Error je něco jako přístup na nulovou adresu v C. Tam je taky zadefinované (na OS s MMU), že to vygeneruje SIGSEGV. Akorát ten error se dá potom v IO chytit. Proč bys proboha něco takového chtěl "normálně" používat? To je funkce, která vůbec není určená pro "normální" použití. Nebo snad normálně používáš přístup na nulovou adresu a chytání SIGSEGV jako "normální" ošetření chyb?
Srovnej s panic v Rustu. To je funkce, která se normálně používá a funguje naprosto definovaně. Volání error v Haskellu by mohlo taky, kdyby se chtělo. Akademikům se nechce, místo toho aby zadefinovali, co přesně volání error dělá, raději se budou tvářit, že je to undefined. I když to klidně můžu zavolat v pure funkci. Se SIGSEGV to nemá nic společného.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 02:05:46
Jaká prasárna v pure kódu? Teď ti vůbec nerozumím. Error je něco jako přístup na nulovou adresu v C. Tam je taky zadefinované (na OS s MMU), že to vygeneruje SIGSEGV. Akorát ten error se dá potom v IO chytit. Proč bys proboha něco takového chtěl "normálně" používat? To je funkce, která vůbec není určená pro "normální" použití. Nebo snad normálně používáš přístup na nulovou adresu a chytání SIGSEGV jako "normální" ošetření chyb?
Srovnej s panic v Rustu. To je funkce, která se normálně používá a funguje naprosto definovaně. Volání error v Haskellu by mohlo taky, kdyby se chtělo. Akademikům se nechce, místo toho aby zadefinovali, co přesně volání error dělá, raději se budou tvářit, že je to undefined. I když to klidně můžu zavolat v pure funkci. Se SIGSEGV to nemá nic společného.
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním. A řešení chyb je přesně to, co musíš v lazy jazyku řešit kompletně jinak. Není totiž přesně definované, kdy vlastně dojde k vyhodnocení toho pure kódu (je to celé lazy!). Takže pokud použiješ "error" pro řešení chyb, tak se ti klidně může stát, že ta výjimka se vyhodí v úplně jiné části programu a klidně třeba i v jiném threadu - prostě tam, kde se zrovna pokusí někdo ta data přečíst. Prostě mimo jakýkoliv "catch", který jsi zrovna napsal.

Tohle je přesně jeden z důvodů, proč Haskell není jenom "další Java-like jazyk s trošku jinou syntaxí". Spousta věcí se řeší diametrálně odlišně a řešení z "normálních" jazyků jsou často zcela nepoužitelná. V pure kódu se prostě výjimky nevyhazují, a je velká snaha se zbavit i partial funkcí, kde to jen jde.

A vzhledem k tomu, že tento způsob řešení chyb je v Haskellu "zapovězen", tak samozřejmě existují jiné mechanismy. Které jsou mnohem lepší. Ono se to těžko popisuje, dokud to člověk nezkusí, ale práce s totálníma funkcema je naprosto jiný kafe.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 02:28:49
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním.
Mohlo. Když už tam ten error je (lepší by bylo, kdyby vůbec nebyl), tak stačí zadefinovat, že volání error ukončí program a vypíše chybu. Ono se to stejně prakticky děje. Prakticky lidi totiž zajímá, jestli nějak rozumně zjistí, co se pokazilo.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 02:33:20
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním.
Mohlo. Když už tam error je (to je další prasárna, lepší by bylo, kdyby vůbec nebyl), tak stačí zadefinovat, že volání error ukončí program a vypíše chybu. Ono se to stejně prakticky děje. Ani to nemusí být chytatelné v catch. Normální uživatele totiž zajímá, jestli nějak rozumně zjistí, co se pokazilo. Akademikům je to jedno, ti si vystačí s nekonečným cyklem.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 06:47:39
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním.
Mohlo. Když už tam error je (to je další prasárna, lepší by bylo, kdyby vůbec nebyl), tak stačí zadefinovat, že volání error ukončí program a vypíše chybu. Ono se to stejně prakticky děje. Ani to nemusí být chytatelné v catch. Normální uživatele totiž zajímá, jestli nějak rozumně zjistí, co se pokazilo. Akademikům je to jedno, ti si vystačí s nekonečným cyklem.
Takže by bylo lepší, kdyby tam byl jenom nekonečný cyklus, ale zároveň je to špatně, protože akademikové si vystačí s nekonečným cyklem a normální programátoři je nezajímají..? A úplně nejpraktičtější by bylo, kdyby podobná záležitost vůbec chytatelná nebyla a místo toho natvrdo ukončila program? Prostě to bude blbě, ať to udělají, jak to udělají...

Generovat výjimku v pure kódu a používat ji ke standardnímu ošetření chyb je prasárna. Bravo, právě jsi zjistil, že když budeš programovat jako prase, tak ti odstranění XStrict může "rozbít" už jednou rozbitý kód. Když budeš programovat jako prase v jiných jazycích, tak můžeš dopadnout úplně stejně. Ale prostě Haskellu to budeš do poslední síly vytýkat...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 07:07:34
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním.
Mohlo. Když už tam error je (to je další prasárna, lepší by bylo, kdyby vůbec nebyl), tak stačí zadefinovat, že volání error ukončí program a vypíše chybu. Ono se to stejně prakticky děje. Ani to nemusí být chytatelné v catch. Normální uživatele totiž zajímá, jestli nějak rozumně zjistí, co se pokazilo. Akademikům je to jedno, ti si vystačí s nekonečným cyklem.
Ještě poznámka k tomu tvému příkladu: on právě nedává sémanticky smysl. Na to, aby dal "správný" výstup, tak vevnitř závisíš na tom, že ti ta pure funkce "nevrátí výsledek". To, že v Haskellu právě díky praktičnosti jsi některé způsoby "nevrácení výsledku" schopen detekovat (v rámci možností dost deterministicky - dokonce i to zacyklení) nemění nic na tom, že ten tvůj program nedává smysl.

Jak píšu od začátku, je to na podobné úrovni, jako když bys v jiných jazycích závisel na nějakém side-efektu. Ono to dokonce může být i popsané a dost deterministické, ale program, jehož správné chování závisí třeba na tom, že se třeba někde vyhodí StackOverflow bys asi taky nepovažoval za dobrý příklad čehokoliv. A asi bys nepsal, že fakt, že StackOverflow je třeba exception a že jde v tom daném jazyce chytat je prasárna...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 08:19:11
Nemohlo. V jazyce, který je lazy, nejde některé věci dělat stejně, jako ve striktním.
Mohlo. Když už tam error je (to je další prasárna, lepší by bylo, kdyby vůbec nebyl), tak stačí zadefinovat, že volání error ukončí program a vypíše chybu. Ono se to stejně prakticky děje. Ani to nemusí být chytatelné v catch. Normální uživatele totiž zajímá, jestli nějak rozumně zjistí, co se pokazilo. Akademikům je to jedno, ti si vystačí s nekonečným cyklem.
Takže by bylo lepší, kdyby tam byl jenom nekonečný cyklus, ale zároveň je to špatně, protože akademikové si vystačí s nekonečným cyklem a normální programátoři je nezajímají..? A úplně nejpraktičtější by bylo, kdyby podobná záležitost vůbec chytatelná nebyla a místo toho natvrdo ukončila program? Prostě to bude blbě, ať to udělají, jak to udělají...
Nepodsouvej mi něco, co jsem nenapsal. Bylo by lepší, kdyby se to chovalo DEFINOVANĚ. Prohlásit o error, který se vyskytuje v pure kódu i v Prelude na mnoha místech, že se chova nedefinovaně, je taková akademická Haskellovská prasárna. Normální lidi mají rádi deterministické programy, o kterých můžou říct, jak se budou chovat. Použitím error se z každého programu v Haskellu stává nedeterministický. Může to udělat v podstatě cokoliv. Když to dovedu ad absurdum, tak můžu říct, že bezpečnost Haskellu je někde na úrovni C, protože s použitím error taky nic nezaručuje a může se stát cokoliv.

Znovu opakuji, podívej se na panic v Rustu. Takhle se to má dělat správně, proti tomu řešení nemám žádné výhrady. Ono to jde, když se chce.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 08:26:28
Ještě poznámka k tomu tvému příkladu: on právě nedává sémanticky smysl. Na to, aby dal "správný" výstup, tak vevnitř závisíš na tom, že ti ta pure funkce "nevrátí výsledek". To, že v Haskellu právě díky praktičnosti jsi některé způsoby "nevrácení výsledku" schopen detekovat (v rámci možností dost deterministicky - dokonce i to zacyklení) nemění nic na tom, že ten tvůj program nedává smysl.
Já nikde netvrdil, že můj program dává sémanticky smysl. Já tvrdil, že lazy versus strict vyhodnocení může změnit výsledek programu a to v Haskellu platí. Ty ses tady snažil tvrdit, že strict je jenom nějaká optimalizace, která mimo časových a paměťových záležitostí nemá sife effecty. Ale to prostě není pravda, v Haskellu to side effecty mít může a může to ovlivnit výsledek programu. A není potřeba řešit, který výstup programu je správně (má to při lazy dělení nulou spadnout, nebo ne?), prostě se to chová při lazy/strict jinak.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 29. 08. 2018, 08:57:07
Nepodsouvej mi něco, co jsem nenapsal. Bylo by lepší, kdyby se to chovalo DEFINOVANĚ. Prohlásit o error, který se vyskytuje v pure kódu i v Prelude na mnoha místech, že se chova nedefinovaně, je taková akademická Haskellovská prasárna. Normální lidi mají rádi deterministické programy, o kterých můžou říct, jak se budou chovat. Použitím error se z každého programu v Haskellu stává nedeterministický. Může to udělat v podstatě cokoliv. Když to dovedu ad absurdum, tak můžu říct, že bezpečnost Haskellu je někde na úrovni C, protože s použitím error taky nic nezaručuje a může se stát cokoliv.

Znovu opakuji, podívej se na panic v Rustu. Takhle se to má dělat správně, proti tomu řešení nemám žádné výhrady. Ono to jde, když se chce.
Sorry, ale tohle je slovíčkaření. Error/panic/assert a všechno podobné znamená, že máš v programu chybu. V computer science je to všechno nedefinované chování, protože pád programu na hubu je čistě implementační záležitost. Je úplně jedno, jak přesně to specifikuješ. Ten error v Haskellu je podobně dobře specifikovaný, jako panic v rustu. Pokud se bavíme o výsledcích, tak ani ten panic v Rustu nemá žádný definovaný výsledek.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 09:02:27
Nepodsouvej mi něco, co jsem nenapsal. Bylo by lepší, kdyby se to chovalo DEFINOVANĚ. Prohlásit o error, který se vyskytuje v pure kódu i v Prelude na mnoha místech, že se chova nedefinovaně, je taková akademická Haskellovská prasárna. Normální lidi mají rádi deterministické programy, o kterých můžou říct, jak se budou chovat. Použitím error se z každého programu v Haskellu stává nedeterministický.
Principálně ano, speciálně, pokud třeba ta pure funkce je paralelizovaná, což klidně překladač může udělat. Může taky provádět spekulativní vyhodnocování apod. Pořadí vyhodnocování v lazy kódu je nedefinované... Ono je samozřejmě většinou vcelku jasné, jak se to vyhodnocuje, ale opravdu, pokud vyhodíš 2 výjimky v nezávislých větvích, které jsou obě potřebné pro vyhdnocení výsledku, tak která z toho vypadne je nedeterministické.

Citace
Může to udělat v podstatě cokoliv.
Fakt? Když je teda v typu, že to vrací Float, tak to vrátí Float nebo bottom. To je cokoliv? No když chceš...

Citace
Když to dovedu ad absurdum, tak můžu říct, že bezpečnost Haskellu je někde na úrovni C, protože s použitím error taky nic nezaručuje a může se stát cokoliv.
To by ovšem bylo poněkud absurdní, vzhledem k tomu, že haskell ti přesně zaručuje, že to pure funkce, kterou voláš, se bude chovat přesně podle toho typu (tzn. vrátí návratovou hodnotu nebo bude bottom). Což se přesně děje...

Citace
Znovu opakuji, podívej se na panic v Rustu. Takhle se to má dělat správně, proti tomu řešení nemám žádné výhrady. Ono to jde, když se chce.
No jestli v tebou napsaném kódu běžně používáš panic pro řešení běžných stavů, tak to potěš...

Ty se strašně divíš, že konstrukce, které jsou vcelku použitelné ve striktních jazycích prostě v lazy jazycích nedávají moc smysl. Ano, nedávají. Proto je taky Haskell považován za tak "těžký", protože i ten blbý error handling musíš dělat jinak.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 09:20:49
Sorry, ale tohle je slovíčkaření. Error/panic/assert a všechno podobné znamená, že máš v programu chybu. V computer science je to všechno nedefinované chování, protože pád programu na hubu je čistě implementační záležitost.
Tobě uniká základní věc, rozdíl mezi undefined behavior a definovaným ukončením programu (ať už standardně nebo chybou). Panic v Rustu NENÍ undefined behaviour. Používá se naprosto standardně, má definované chování a řeší situace, kdy nastane unrecoverable error. Zkus si trochu rozšířit obzory a nastudovat třeba tohle: https://doc.rust-lang.org/book/second-edition/ch09-03-to-panic-or-not-to-panic.html. Ukončení programu (ať už panicem nebo errorem) nemá být implementační záležitost. Haskell to má blbě, protože v Haskellu to implementační záležitost je a dokonce se ten program ani ukončit nemusí a zůstane v nekonečném cyklu... Tohle je prostě špatný design a s computer science to má společného možná jenom to, že computer science nedefinuje, co přesně se má v programu stát, když nastane unrecoverable error, takže Haskell akademici (včetně tebe) si to vyložili tak, že je to vlasně úplně jedno a nemusí to řešit. Normálním lidem to ale jedno není a řešit to chtějí.

Je úplně jedno, jak přesně to specifikuješ. Ten error v Haskellu je podobně dobře specifikovaný, jako panic v rustu. Pokud se bavíme o výsledcích, tak ani ten panic v Rustu nemá žádný definovaný výsledek.
Panic v Rustu má definovaný výsledek. Program se ukončí na na výstup se vypíše chyba. Chyba na výstupu je definovaný výsledek.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 09:29:12
Ukončení programu (ať už panicem nebo errorem) nemá být implementační záležitost. Haskell to má blbě, protože v Haskellu to implementační záležitost je a dokonce se ten program ani ukončit nemusí a zůstane v nekonečném cyklu...
Ale ono je to popsané IMO i v haskell reportu, že se to chová tak, jak se to chová. O to vůbec nejde - takhle dopadaj zkratky v diskuzích...

Jde o to, že se snažíš příklad rozbitého programu (v normálním flow má error) prezentovat jako "nerozbitý", který následně odstranění XStrict rozbije. Tak se ti snažím nějak vysvětlit, že pokud má v normálním flow "error", tak už to je rozbité.

Chápu, že ty "nechceš", aby měl error takovouhle sémantiku, a protože ty to "nechceš" a tobě se "líbí", když s tím můžeš normálně pracovat, protože naprosto běžně používáš panic pro řešení chybových stavů. Tobě se "líbí", když můžeš z pure funkce vyhodit výjimku a pak s ní normálně pracovat a to, že v Haskellu tímhle způsobem nejde udělat (resp. se to nepovažuje za korektní), je prostě "špatně".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 09:30:04
Může to udělat v podstatě cokoliv.
Fakt? Když je teda v typu, že to vrací Float, tak to vrátí Float nebo bottom. To je cokoliv? No když chceš...
Nebo to taky nemusí skončit a zůstat v nekonečné smyčce. Nebo to taky může udělat něco úplně jiného, pokud ten error odchytím (jen v případě, že to předtím, neskončilo v nekonečné smyčce...).

Citace
No jestli v tebou napsaném kódu běžně používáš panic pro řešení běžných stavů, tak to potěš...
Nevyjadřuj se k něčemu, o čem máš jen mlhavé představy. Panic v Rustu je defaultní chování při unwrap optionu, pokud je prázdný. To je naprosto legitimní použití, nikdo proto tomu neprotestuje a nikdo se toho nechce zbavit. V Rustu panic funguje deterministicky, narozdíl od error v Haskellu.

Ty se strašně divíš, že konstrukce, které jsou vcelku použitelné ve striktních jazycích prostě v lazy jazycích nedávají moc smysl. Ano, nedávají. Proto je taky Haskell považován za tak "těžký", protože i ten blbý error handling musíš dělat jinak.
Když error v Haskellu nedává smysl, nemá tam být. Pak totiž přijde nějaká lopata, použije ho v pure funkci (proč by ne, dělají to tak i v Prelude) a ono to má ve skutečnosti nedefinované chování...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 09:38:34
Ukončení programu (ať už panicem nebo errorem) nemá být implementační záležitost. Haskell to má blbě, protože v Haskellu to implementační záležitost je a dokonce se ten program ani ukončit nemusí a zůstane v nekonečném cyklu...
Ale ono je to popsané IMO i v haskell reportu, že se to chová tak, jak se to chová. O to vůbec nejde - takhle dopadaj zkratky v diskuzích...
Aha, takže Haskell má ukončení po erroru udělané blbě, ale ono to nevadí, protože je popsané v Haskell reportu, že je to blbě... To můžu říct o C, že je dokonalý jazyk, protože všechny prasárny, které můžu v C udělat, mají popsané chování ve standardu (jako undefined behavior).

Jde o to, že se snažíš příklad rozbitého programu (v normálním flow má error) prezentovat jako "nerozbitý", který následně odstranění XStrict rozbije. Tak se ti snažím nějak vysvětlit, že pokud má v normálním flow "error", tak už to je rozbité.
Hele tohle byl jen příklad. Jsou i jiné způsoby, jak v Haskellu mít jiný výstup při strict/lazy vyhodnocení a nemusí tam být error. Třeba unsafePerformIO. Je mi jasné, že řekneš, že unsafePerformIO je prasárna (ano je) a nemá se používat. Ale reálně se unsafePerformIO používá i v některých knihovnách.

Chápu, že ty "nechceš", aby měl error takovouhle sémantiku, a protože ty to "nechceš" a tobě se "líbí", když s tím můžeš normálně pracovat, protože naprosto běžně používáš panic pro řešení chybových stavů. Tobě se "líbí", když můžeš z pure funkce vyhodit výjimku a pak s ní normálně pracovat a to, že v Haskellu tímhle způsobem nejde udělat (resp. se to nepovažuje za korektní), je prostě "špatně".
Mně je úplně jedno, jakou má error sémantiku, pro mě za mě tam vůbec nemusí být. Já ale chci, aby to bylo definované. A definicí nemyslím "většinou to skončí výpisem chyby na výstup, ale někdy taky ne, může to třeba skončit i nekonečným cyklem".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 09:51:06
Když error v Haskellu nedává smysl, nemá tam být. Pak totiž přijde nějaká lopata, použije ho v pure funkci (proč by ne, dělají to tak i v Prelude) a ono to má ve skutečnosti nedefinované chování...
Ale on dává smysl... říká "pokud se tohle spustilo, tak je ten kód rozbitý". Internal error. Proč by něco takového nemělo v jazyce být? Pomáhá to programátorům hledat bugy.

Nebo tam nemá být, protože přijde lopata a je strašně uražena, že se to nadá použít stejně jako panic v Rustu? Oni v tom Prelude totiž tu výjimku nechytají, což bylo první, co lopatu napadlo...

Citace
Aha, takže Haskell má ukončení po erroru udělané blbě, ale ono to nevadí, protože je popsané v Haskell reportu, že je to blbě... To můžu říct o C, že je dokonalý jazyk, protože všechny prasárny, které můžu v C udělat, mají popsané chování ve standardu (jako undefined behavior).
Ale ne... že v haskell reportu bude popsaný, že to tu výjimku vyhodí... ono to dřív (tzn. třeba před těma 20 lety) skutečně byl jeden z mála rozumných způsob error reportingu a běžně se používal - dneska je to jinak.

Citace
Hele tohle byl jen příklad. Jsou i jiné způsoby, jak v Haskellu mít jiný výstup při strict/lazy vyhodnocení a nemusí tam být error. Třeba unsafePerformIO. Je mi jasné, že řekneš, že unsafePerformIO je prasárna (ano je) a nemá se používat. Ale reálně se unsafePerformIO používá i v některých knihovnách.
WTF??? Jsou i jiné způsoby, jak C/C++/Java atd. se chovají třeba nedeterministicky. Například většina umožňuje volání ASM, externích C funkcí apod. Jasně že řekneš, že to je prasárna, ale reálně se to používá i v některých knihovnách....

Citace
Mně je úplně jedno, jakou má error sémantiku, pro mě za mě tam vůbec nemusí být. Já ale chci, aby to bylo definované. A definicí nemyslím "většinou to skončí výpisem chyby na výstup, ale někdy taky ne, může to třeba skončit i nekonečným cyklem".
No v implementaci GHC to definované máš. What's the problem? Ale to, co se ti snažím říct je, že tvoje funkce nemá definovaný výstup. A je poněkud otázka, jak má jazyk definovat chování tvého programu, který není v ten moment definovaný. No a konkrétní implementace překladače pak řeší jak tobě pomoci najít ve tvém programu tu chybu...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 29. 08. 2018, 10:07:52
Tobě uniká základní věc, rozdíl mezi undefined behavior a definovaným ukončením programu (ať už standardně nebo chybou). Panic v Rustu NENÍ undefined behaviour. Používá se naprosto standardně, má definované chování a řeší situace, kdy nastane unrecoverable error. Zkus si trochu rozšířit obzory a nastudovat třeba tohle: https://doc.rust-lang.org/book/second-edition/ch09-03-to-panic-or-not-to-panic.html. Ukončení programu (ať už panicem nebo errorem) nemá být implementační záležitost. Haskell to má blbě, protože v Haskellu to implementační záležitost je a dokonce se ten program ani ukončit nemusí a zůstane v nekonečném cyklu... Tohle je prostě špatný design a s computer science to má společného možná jenom to, že computer science nedefinuje, co přesně se má v programu stát, když nastane unrecoverable error, takže Haskell akademici (včetně tebe) si to vyložili tak, že je to vlasně úplně jedno a nemusí to řešit. Normálním lidem to ale jedno není a řešit to chtějí.
Ani ten error v haskellu není nedefinované chování. Je to nedefinovaná hodnota funkce pro nějaký vstup. Nezapomeň, že v haskellu řešíme pure funkce. Ty nemají žádné chování. Ty mají hodnotu pro nějaké vstupy. Crash programu není hodnota funkce. Jestli si u haskellových funkcí představuješ, že "něco dělají", pak začínám chápat proč si nerozumíme.

A tohle není specifické pro Haskell. I v C (třeba v gcc) můžeš anotovat funkce jako pure. A pak může nastat přesně to samé co v haskellu. Překladač může přesouvat vyhodnocení funkce podle chuti kamkoliv. Pokud taková funkce assertí (dostala vstupy pro které nemá definovanou hodnotu), pak se chování toho (zabugovaného) programu může lišit podle nastavení optimalizací a podle spousty dalších věcí.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 10:12:52
Ale on dává smysl... říká "pokud se tohle spustilo, tak je ten kód rozbitý". Internal error. Proč by něco takového nemělo v jazyce být? Pomáhá to programátorům hledat bugy.
To mi řekni, jak programátorům pomáhá hledat bugy, když to chybu nemusí vůbec vypsat a skončí to v nekonečné smyčce? Autoři Haskellu asi předpokládají, že si udělám memory dump procesu a v něm budu hledat chybovou hlášku, která zrovna nastala.

Citace
WTF??? Jsou i jiné způsoby, jak C/C++/Java atd. se chovají třeba nedeterministicky. Například většina umožňuje volání ASM, externích C funkcí apod. Jasně že řekneš, že to je prasárna, ale reálně se to používá i v některých knihovnách....
Původně debata začala tak, že jsem tvrdil, že výsledek kódu v Haskellu může záviset na lazy/strict vyhodnocení a pokud použiješ zrovna to nesprávné, může dávat jiné výsledky. To platí minimálně v případech, kdy je v Haskell kódu error nebo unsafePerformIO (asi i v jindy). Protože se obojí v reálném Haskell kódu vyskytuje, nemůžu jen tak vzít nějaký Haskell kód a přeložit ho s XStrict bez XStrict a očekávat, že dostanu stejný výsledek. Je úplně jedno, kde ta prasárna vzniká, jestli ji dělá error, unsafePerformIO nebo něco jiného, reálně se na to nemůžu vykašlat a musím se tím zabývat.

No v implementaci GHC to definované máš. What's the problem?
Takže můj program má pod GHC definované chování. What's the problem?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 10:34:13
Ale on dává smysl... říká "pokud se tohle spustilo, tak je ten kód rozbitý". Internal error. Proč by něco takového nemělo v jazyce být? Pomáhá to programátorům hledat bugy.
To mi řekni, jak programátorům pomáhá hledat bugy, když to chybu nemusí vůbec vypsat a skončí to v nekonečné smyčce? Autoři Haskellu asi předpokládají, že si udělám memory dump procesu a v něm budu hledat chybovou hlášku, která zrovna nastala.
Nerozumím. Konkrétní implementace Haskellu (GHC) samozřejmě vyhazuje výjimku. To, že tvůj program je nedefinovaný a jiný překladač se s tím teoreticky může vyrovnat jinak je druhá věc. Prostě ty ses tady snažil tvrdit, že tvůj program "rozbije" XStrict - jenomže tvůj program byl rozbitý už předtím. Akorát GHC ti dává možnosti to v některých případech odchytit a zpracovat. Pokud na tomhle chování závisí korektní chování tvého programu, tak jsi v podstatě v situaci různých nedefinovaných chování C/C++ - která ale klidně daný překladač může mít zcela přesně definované ve své specifikaci a dodržovat to.
Citace
Citace
WTF??? Jsou i jiné způsoby, jak C/C++/Java atd. se chovají třeba nedeterministicky. Například většina umožňuje volání ASM, externích C funkcí apod. Jasně že řekneš, že to je prasárna, ale reálně se to používá i v některých knihovnách....
Původně debata začala tak, že jsem tvrdil, že výsledek kódu v Haskellu může záviset na lazy/strict vyhodnocení a pokud použiješ zrovna to nesprávné, může dávat jiné výsledky. To platí minimálně v případech, kdy je v Haskell kódu error nebo unsafePerformIO (asi i v jindy). Protože se obojí v reálném Haskell kódu vyskytuje, nemůžu jen tak vzít nějaký Haskell kód a přeložit ho s XStrict bez XStrict a očekávat, že dostanu stejný výsledek. Je úplně jedno, kde ta prasárna vzniká, jestli ji dělá error, unsafePerformIO nebo něco jiného, reálně se na to nemůžu vykašlat a musím se tím zabývat.
Ach jo...

Ano, když odstraníš XStrict z rozbitého kódu, tak může změnit výstup.
Ano, když odstraníš/přidáš XStrict ke kódu, kde je explicitně napsáno "tento kód nebude vykonáván podle haskellové sémantiky (ať už lazy nebo strict)", tak se taky může stát vcelku cokoliv (zrovna u toho unsafePerformIO opravdu vcelku cokoliv).
Ano, když budeš mít C++ s odskokem do ASM, kde ti bude šahat na nějaké interní struktury, tak ti to taky různé jinak zcela nevinné optimalizační a další flagy můžou pěkně poprasit.

A teď co teda vlastně říkáš? Že je z tohoto hlediska Haskell na tom úplně stejně jako všechny ostatní reálně používané jazyky?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 12:03:14
Nerozumím. Konkrétní implementace Haskellu (GHC) samozřejmě vyhazuje výjimku.
To je pořád dokola. Je nějaká jazyková konstrukce (error), která se dá volat v pure funkcích. Má nedefinované chování. V konkrétní implementaci (GHC) definované chování má. Co s tím jako uživatel mám jako dělat? Nezbývá mi nic jiného, než používat GHC, protože error se používá i v Prelude. Opravdu nechci, aby měly moje programy nedefinované chování. Můžu reálně použít neco jiného, než GHC? Nemůžu. Leda že bych si předem ověřil, co konkrétně tam error dělá. Error dělá všechny Haskell programy neportabilní. Můžeš 1000x argumentovat tím, že je jedno, co se po error stane, ale reálně není. Můžu požadovat, jak je obvyklé, aby se po erroru program ukončí a vrátil nějaký exit code, když error nebudu explicitně chytat a ošetřovat (což je taky neportabilní). Jenomže Haskell mi ani takovou základní věc nezaručuje. Nedozvím se, že v programu nastala chyba, nemusí to ani skončit a vrátit exit code.

Ano, když odstraníš XStrict z rozbitého kódu, tak může změnit výstup.
Ano, když odstraníš/přidáš XStrict ke kódu, kde je explicitně napsáno "tento kód nebude vykonáván podle haskellové sémantiky (ať už lazy nebo strict)", tak se taky může stát vcelku cokoliv (zrovna u toho unsafePerformIO opravdu vcelku cokoliv).
Ano, když budeš mít C++ s odskokem do ASM, kde ti bude šahat na nějaké interní struktury, tak ti to taky různé jinak zcela nevinné optimalizační a další flagy můžou pěkně poprasit.

A teď co teda vlastně říkáš? Že je z tohoto hlediska Haskell na tom úplně stejně jako všechny ostatní reálně používané jazyky?
Ještě jsi zapomněl na případ, kdy přidám XStrict a rozbiju korektní lazy kód, ale to je celkem jedno. Ano, říkám, že Haskell na tom není líp, než ostatní reálně používané jazyky. Prakticky je na tom hůř, protože míchá dohromady strict a lazy vyhodnocení, půlka kódu se může vyhodnocovat lazy a druhá strict. Kód je závislý na konkrétním způsobu vyhodnocení, nejde to jen tak změnit a očekávat, že se nic nerozbije. Tohle je mimo možnosti běžné lopaty, stupeň volnosti je příliš vysoký, normální člověk nedomyslí důsledky a bude dělat chyby. Jazyk by měl být navržený tak, aby minimalizoval možnost udělat chybu, pro Haskell to ale bohužel neplatí.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 29. 08. 2018, 12:46:58
Nerozumím. Konkrétní implementace Haskellu (GHC) samozřejmě vyhazuje výjimku.
To je pořád dokola. Je nějaká jazyková konstrukce (error), která se dá volat v pure funkcích. Má nedefinované chování. V konkrétní implementaci (GHC) definované chování má. Co s tím jako uživatel mám jako dělat? Nezbývá mi nic jiného, než používat GHC, protože error se používá i v Prelude. Opravdu nechci, aby měly moje programy nedefinované chování. Můžu reálně použít neco jiného, než GHC? Nemůžu. Leda že bych si předem ověřil, co konkrétně tam error dělá. Error dělá všechny Haskell programy neportabilní. Můžeš 1000x argumentovat tím, že je jedno, co se po error stane, ale reálně není. Můžu požadovat, jak je obvyklé, aby se po erroru program ukončí a vrátil nějaký exit code, když error nebudu explicitně chytat a ošetřovat (což je taky neportabilní). Jenomže Haskell mi ani takovou základní věc nezaručuje. Nedozvím se, že v programu nastala chyba, nemusí to ani skončit a vrátit exit code.

Ano, když odstraníš XStrict z rozbitého kódu, tak může změnit výstup.
Ano, když odstraníš/přidáš XStrict ke kódu, kde je explicitně napsáno "tento kód nebude vykonáván podle haskellové sémantiky (ať už lazy nebo strict)", tak se taky může stát vcelku cokoliv (zrovna u toho unsafePerformIO opravdu vcelku cokoliv).
Ano, když budeš mít C++ s odskokem do ASM, kde ti bude šahat na nějaké interní struktury, tak ti to taky různé jinak zcela nevinné optimalizační a další flagy můžou pěkně poprasit.

A teď co teda vlastně říkáš? Že je z tohoto hlediska Haskell na tom úplně stejně jako všechny ostatní reálně používané jazyky?
Ještě jsi zapomněl na případ, kdy přidám XStrict a rozbiju korektní lazy kód, ale to je celkem jedno. Ano, říkám, že Haskell na tom není líp, než ostatní reálně používané jazyky. Prakticky je na tom hůř, protože míchá dohromady strict a lazy vyhodnocení, půlka kódu se může vyhodnocovat lazy a druhá strict. Kód je závislý na konkrétním způsobu vyhodnocení, nejde to jen tak změnit a očekávat, že se nic nerozbije. Tohle je mimo možnosti běžné lopaty, stupeň volnosti je příliš vysoký, normální člověk nedomyslí důsledky a bude dělat chyby. Jazyk by měl být navržený tak, aby minimalizoval možnost udělat chybu, pro Haskell to ale bohužel neplatí.
Sorry, ale pořád dokola řešíš naprostou koninu. Prakticky ti tohle nedefinované chování může být úplně ukradené. Není to nedefinované chování ve významu z C/C++.

Všechny implementace při volání error provedou něco, podle čeho můžeš identifikovat, co máš v programu špatně. A žádná ani v principu nemůže provést něco, co bys chtěl aby se stávalo u zákazníka. Jestli při volání error program vypíše něco do konzole, segfaultuje, nebo zatuhne a zabije ho watchdog je na zákaznickém stroji +- putna. Není to úplně identické, ale nějaký zásadní rozdíl v tom není.

A to, že se na tu chybu nemusí přijít vždycky je naprosto normální ve všech programovacích jazycích, co znám. To vyhodnocení může přerovnat optimalizátor, plánovač vláken, nebo se třeba může změnit hashovací funkce pro kontejner callbacků. Jestli spoléháš na to, že ti zabugovaný kód vždycky zavolá panic, tak to raději nedělej.

Jo, XStrict může rozbít korektní lazy kód. Jenže :
- Když můj kód vyžaduje lazy vyhodnocení, tak xstrict samozřejmě nepoužiju. Úplně stejně nepoužiju -ffast-math, pokud vyžaduju striktní floatovou sémantiku.
- V praxi se takový kód vyskytuje minimálně. Já se s ním potkal jenom v ukázkových příkladech.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 13:03:41
Hlavně pořád bychom rádi viděli případ, kdy lazy evaluation rozbije strict kód...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 13:58:13
Hlavně pořád bychom rádi viděli případ, kdy lazy evaluation rozbije strict kód...
Definuj rozbije. Dostaneš jiný výstup.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 14:04:23
Všechny implementace při volání error provedou něco, podle čeho můžeš identifikovat, co máš v programu špatně. A žádná ani v principu nemůže provést něco, co bys chtěl aby se stávalo u zákazníka. Jestli při volání error program vypíše něco do konzole, segfaultuje, nebo zatuhne a zabije ho watchdog je na zákaznickém stroji +- putna. Není to úplně identické, ale nějaký zásadní rozdíl v tom není.
Sorry, ale jsi úplně mimo. Vůbec nemáš ponětí o řízení kvality a o tom, jak nasazovat a provozovat aplikaci u zákazníka. Pokud aplikace u zákazníka spadne, tak chci sakra co nejrychleji a co nejpodrobněji vědět, co se stalo a proč. Protože zákazník na mě bude řvát, že mu to nefunguje a že mi nezaplatí. Zákazníka vůbec nezajímá, že ty si myslíš, že je +- putna co to dělá na jeho stroji. On chce, aby to fungovalo.

A to, že se na tu chybu nemusí přijít vždycky je naprosto normální ve všech programovacích jazycích, co znám. To vyhodnocení může přerovnat optimalizátor, plánovač vláken, nebo se třeba může změnit hashovací funkce pro kontejner callbacků. Jestli spoléháš na to, že ti zabugovaný kód vždycky zavolá panic, tak to raději nedělej.
Panic není žádná magie. V normální jazycích (mimo Haskell) se chová deterministicky.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 29. 08. 2018, 14:57:40
Všechny implementace při volání error provedou něco, podle čeho můžeš identifikovat, co máš v programu špatně. A žádná ani v principu nemůže provést něco, co bys chtěl aby se stávalo u zákazníka. Jestli při volání error program vypíše něco do konzole, segfaultuje, nebo zatuhne a zabije ho watchdog je na zákaznickém stroji +- putna. Není to úplně identické, ale nějaký zásadní rozdíl v tom není.
Sorry, ale jsi úplně mimo. Vůbec nemáš ponětí o řízení kvality a o tom, jak nasazovat a provozovat aplikaci u zákazníka. Pokud aplikace u zákazníka spadne, tak chci sakra co nejrychleji a co nejpodrobněji vědět, co se stalo a proč. Protože zákazník na mě bude řvát, že mu to nefunguje a že mi nezaplatí. Zákazníka vůbec nezajímá, že ty si myslíš, že je +- putna co to dělá na jeho stroji. On chce, aby to fungovalo.
No právě proto, že to potřebuju co nejrychleji vědět, tak musí error handler posbírat zbytky a poslat mi je. A je celkem jedno, jestli ten program něco vypíše do konzole, segfaultuje, nebo jak konkrétně umře. Prostě umře a dostanu zbytky. V tom crashdumpu se bude lišit jak přesně umřel a to je tak všechno.
Prakticky je ten error dostatečně dobře definovaný i v haskellu. V kontextu funkcionálního programování ta nedefinované hodnota znamená jenom to, že ta funkce nevrátila hodnotu a stalo se něco jiného.
Citace
A to, že se na tu chybu nemusí přijít vždycky je naprosto normální ve všech programovacích jazycích, co znám. To vyhodnocení může přerovnat optimalizátor, plánovač vláken, nebo se třeba může změnit hashovací funkce pro kontejner callbacků. Jestli spoléháš na to, že ti zabugovaný kód vždycky zavolá panic, tak to raději nedělej.
Panic není žádná magie. V normální jazycích (mimo Haskell) se chová deterministicky.
I ten error není žádná magie a chová se deterministicky. Jen se díky rozdílu strict vs lazy může ta chyba detekovat malinko jindy. V praxi je to srovnatelné s nedeterminismem z jiných zdrojů. Že se půl programu neprovede je možné jenom v syntetických ukázkách odtržených od reality.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 15:57:29
No právě proto, že to potřebuju co nejrychleji vědět, tak musí error handler posbírat zbytky a poslat mi je. A je celkem jedno, jestli ten program něco vypíše do konzole, segfaultuje, nebo jak konkrétně umře. Prostě umře a dostanu zbytky. V tom crashdumpu se bude lišit jak přesně umřel a to je tak všechno.
Tak zaprvé crashdump ti typicky nikdo nedá, protože v tom můžou být citlivá data (šifrovací klíče, data z databáze...) a zadruhé těžko něco dostaneš, když je chování error nedefinované a může skončit v nekonečné smyčce...

Prakticky je ten error dostatečně dobře definovaný i v haskellu. V kontextu funkcionálního programování ta nedefinované hodnota znamená jenom to, že ta funkce nevrátila hodnotu a stalo se něco jiného.
Kde "něco jiného" může být "cokoliv".

I ten error není žádná magie a chová se deterministicky. Jen se díky rozdílu strict vs lazy může ta chyba detekovat malinko jindy. V praxi je to srovnatelné s nedeterminismem z jiných zdrojů. Že se půl programu neprovede je možné jenom v syntetických ukázkách odtržených od reality.
Jak deterministicky? Je zaručeno, že error neskončí v nekonečné smyčce? Je zaručeno, že ukončí program a vypíše smysluplnou chybu na výstup?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 29. 08. 2018, 16:10:50
https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Citace
A call to error terminates execution of the program and returns an appropriate error indication to the operating system.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 19:46:55
Všechny implementace při volání error provedou něco, podle čeho můžeš identifikovat, co máš v programu špatně. A žádná ani v principu nemůže provést něco, co bys chtěl aby se stávalo u zákazníka. Jestli při volání error program vypíše něco do konzole, segfaultuje, nebo zatuhne a zabije ho watchdog je na zákaznickém stroji +- putna. Není to úplně identické, ale nějaký zásadní rozdíl v tom není.
Sorry, ale jsi úplně mimo. Vůbec nemáš ponětí o řízení kvality a o tom, jak nasazovat a provozovat aplikaci u zákazníka. Pokud aplikace u zákazníka spadne, tak chci sakra co nejrychleji a co nejpodrobněji vědět, co se stalo a proč. Protože zákazník na mě bude řvát, že mu to nefunguje a že mi nezaplatí. Zákazníka vůbec nezajímá, že ty si myslíš, že je +- putna co to dělá na jeho stroji. On chce, aby to fungovalo.

Naopak, jde vidět, že ví, o čem mluví. Zatím jsi mimo spíš ty - minimálně co se Haskellu týče nás o tom přesvědčuješ celé vlákno.

Hlavně pořád bychom rádi viděli případ, kdy lazy evaluation rozbije strict kód...
Definuj rozbije. Dostaneš jiný výstup.

Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné). Zatím jsi ukázal kód, který 1) to měl obráceně 2) nebyl funkční.

https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Citace
A call to error terminates execution of the program and returns an appropriate error indication to the operating system.

Někomu se tu teď zhroutil svět  :o
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Radek 29. 08. 2018, 20:28:44
Citace: Cikáda
Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné).

Nestačí pouhé
Kód: [Vybrat]
foldl (+) hodneDlouhySeznamCisel?

To vybuchne na stack overflow.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 20:52:32
Citace: Cikáda
Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné).

Nestačí pouhé
Kód: [Vybrat]
foldl (+) hodneDlouhySeznamCisel?

To vybuchne na stack overflow.

To je zajímavá myšlenka, ale ne. Ano, lazy evaluation je žravější, tudíž může vést častěji k nedostatku systémových prostředků, ale není to "rozbití" jakožto spíše "nešikovnost programátora." (hned mne napadlo srovnání s nevhodnou rekurzivní funkcí -> rekurze to rozbije)
Měl jsem namysli případ v kontextu diskuse, tedy pod strictem něco funguje a s lazy to fungovat přestane, resp. změní to chování/výstup (stack overflow je spíš nešikovnost autora).

Ale děkuji za snahu :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 22:15:59
Naopak, jde vidět, že ví, o čem mluví. Zatím jsi mimo spíš ty - minimálně co se Haskellu týče nás o tom přesvědčuješ celé vlákno.
Kecy v kleci.

Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné). Zatím jsi ukázal kód, který 1) to měl obráceně 2) nebyl funkční.

https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
A call to error terminates execution of the program and returns an appropriate error indication to the operating system.

Někomu se tu teď zhroutil svět  :o
Máte v tom zmatek hoši od Haskellu. Andy tvrdí, že error má nedefinované chování a může skončit v nekonečné smyčce. Ty tvrdíš, že nemůže.  Reálně se navíc ten error dá chytit, takže to ve skutečnosti funguje ještě jinak. Ono je pak těžké něco dělat, když každý tvrdí něco jiného. Ale dobře, dejme tomu, že máš pravdu a error se chová definovaně. Tak tady máš ten kód, který funguje ve strict režimu a v lazy ne:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

myDiv :: Float -> Float -> IO Float
myDiv x 0 = error "Tímto číslem nelze dělit"
myDiv x y = return (x / y)

main = catch
          (do
                putStrLn "Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo"
                input <- getLine
                let n = (read input :: Float)
                let a = myDiv 1 n
                putStrLn "Tímto číslem lze dělit"
          )
          (\(err :: SomeException) -> putStrLn "Tímto číslem nelze dělit")

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
Tímto číslem nelze dělit

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
Tímto číslem lze dělit

Je mi jasné, že odchycení erroru bude podle vás taky nedefinované (težko říct, na co se vlastně člověk v Haskellu může spolehnout...), takže i verze bez něj, ať si ušetříme další kolečko, než si sami ujasníte, jak má co vlastně v Haskellu fungovat. Verze bez chytání erroru funguje taky, jen není tak elegantní:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

myDiv :: Float -> Float -> IO Float
myDiv x 0 = error "Tímto číslem nelze dělit"
myDiv x y = return (x / y)

main = do   
        putStrLn "Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo"
        input <- getLine
        let n = (read input :: Float)
        let a = myDiv 1 n
        putStrLn "Tímto číslem lze dělit"

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
test: Tímto číslem nelze dělit
CallStack (from HasCallStack):
  error, called at test.hs:6:13 in main:Main

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
Tímto číslem lze dělit
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 22:36:14
Citace
Máte v tom zmatek hoši od Haskellu. Andy tvrdí, že error má nedefinované chování a může skončit v nekonečné smyčce.
Ach jo.. to je zase zkratka v internetové diskuzi... nevím, jestli jsi měl někde vyčíslitelnost, ale v principu pokud částečně rekurzivní funkce buď vrátí hodnotu nebo ji nevrátí - což v podstatě znamená, že se zacyklí. To je samozřejmě z hlediska programování blbý, protože přece jenom to z hlediska debuggingu a vůbec třeba nějakého error recovery není pro programátory příjemné, tudíž v haskellu je možné zavolat "error", který to v rámci možností jakž takž deterministicky utne a vyhodí výjimku, kterou je možné i chytit a případně provést teda nějakou error recovery. Sémantika celého toho kusu kódu je: JE TO ROZBITÝ. Protože bottom je non-observable, tak pokud z toho, že ti tam vylítla ta výjimka usuzuješ cokoliv jiného než "je to rozbitý", tak to je chybně napsaný kód. Kromě toho, že to je prostě sémanticky blbě, tak čistě prakticky můžeš třeba dostat MemoryError, StackOverflow, nebo klidně nějakou asynchronní výjimku z nějakého jiného threadu (jakoukoliv).

Takže všechny ty tvoje příklady jsou blbě, protože to klidně v principu může napsat "Tímto číslem nelze dělit" v důsledku nějaké výjimky, a přitom to klidně dělitelné být může. Bavit se o tom, jestli odstranění/přidání XStrict rozbije chybný kód fakt nemá smysl, proto zněla otázka, jestli bys mohl postnout korektní kód.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 22:52:42
Takže všechny ty tvoje příklady jsou blbě, protože to klidně v principu může napsat "Tímto číslem nelze dělit" v důsledku nějaké výjimky, a přitom to klidně dělitelné být může. Bavit se o tom, jestli odstranění/přidání XStrict rozbije chybný kód fakt nemá smysl, proto zněla otázka, jestli bys mohl postnout korektní kód.
Víš, on je to elementární příklad. U elementárních příkladů už to tak bývá, že neřeší konkrétní problém, jsou osekané na kost a mají ukázat nějakou vlastnost. Tady konkrétně to, že výsledek strict a lazy vyhodnocení může být v Haskellu jiný a může to způsobit neočekávané chování programu. Můžeš samozřejmě tvrdit, že je ten elementární příklad blbě a mělo by se to dělat nějak jinak, ale základní fakt, že lazy vyhodnocení může změnit výstup programu, popřít nemůžeš. Taky můžeš tvrdit, že je to vymyšlený příklad a v praxi nic podobného nenastane, ale obávám se, že je to nedokazatelné tvrzení.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 29. 08. 2018, 22:58:57
Citace: Cikáda
Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné).

Nestačí pouhé
Kód: [Vybrat]
foldl (+) hodneDlouhySeznamCisel?

To vybuchne na stack overflow.
ale to by musel být foldl definovaný v modulu ve kterém přepneme Strict, ne? pokud bude z knihovny tak to Strict neovlivní, ne?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 23:02:06
Naopak, jde vidět, že ví, o čem mluví. Zatím jsi mimo spíš ty - minimálně co se Haskellu týče nás o tom přesvědčuješ celé vlákno.
Kecy v kleci.

Si to přečti ;)

Ne, chci vidět příklad kódu, který funguje korektně ve strict režimu a jeho vypnutím (tj. "s výchozím" lazy evaluation) přestane fungovat (obávám se, že to není možné). Zatím jsi ukázal kód, který 1) to měl obráceně 2) nebyl funkční.

https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
A call to error terminates execution of the program and returns an appropriate error indication to the operating system.

Někomu se tu teď zhroutil svět  :o
Tak tady máš ten kód, který funguje ve strict režimu a v lazy ne:
Kód: [Vybrat]
spoooooousta hnusných věcí

Takže mi chceš říct, že jako příklad korektního kódu je podle tebe kód, který rozhoduje na základě toho, zdali se k vykonávání řádku dostaneme, nebo chcípneme po cestě?

nevím, jestli jsi měl někde vyčíslitelnost

Z vlákna soudím, že nikoliv.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 23:09:06
Takže všechny ty tvoje příklady jsou blbě, protože to klidně v principu může napsat "Tímto číslem nelze dělit" v důsledku nějaké výjimky, a přitom to klidně dělitelné být může. Bavit se o tom, jestli odstranění/přidání XStrict rozbije chybný kód fakt nemá smysl, proto zněla otázka, jestli bys mohl postnout korektní kód.
Víš, on je to elementární příklad. U elementárních příkladů už to tak bývá, že neřeší konkrétní problém, jsou osekané na kost a mají ukázat nějakou vlastnost. Tady konkrétně to, že výsledek strict a lazy vyhodnocení může být v Haskellu jiný a může to způsobit neočekávané chování programu. Můžeš samozřejmě tvrdit, že je ten elementární příklad blbě
Ano, to tvrdím.

Citace
ale základní fakt, že lazy vyhodnocení může změnit výstup programu, popřít nemůžeš.
To taky nikdo nepopírá. Popírá, že tím můžeš "rozbít" program. A nemůžeš "rozbít" program, který už je rozbitý, jenom úplně náhodou dává dobré výsledky.

Citace
Taky můžeš tvrdit, že je to vymyšlený příklad a v praxi nic podobného nenastane, ale obávám se, že je to nedokazatelné tvrzení.
Lama programátorů je samozřejmě hodně a zaslouží si, aby jim takovéhle programy padaly na hlavu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:10:36
Takže mi chceš říct, že jako příklad korektního kódu je podle tebe kód, který rozhoduje na základě toho, zdali se k vykonávání řádku dostaneme, nebo chcípneme po cestě?
Definuj korektní kód. Závisí ten můj kód někde na undefined behavior? Nezávisí. Dělá věci tak, jak by se normálně dělat měly? Nedělá. Může reálně nastat, že někoho napadne udělat podobnou věc? Může. Zaručuje Haskell, že výsledek strict a lazy vyhodnocení bude stejný? Nezaručuje. Musím se rozdíly mezi strict a lazy vyhodnocením zabývat, když chci ho převzít cizí kód? Musím, protože se nemůžu spoléhat na to, že někdo nevymyslí podobnou prasárnu. Máš ještě v něčem zmatek a potřebuješ to dále vysvětlit? Rád ti pomohu. Mám docela trpělivost a věřím, že jsi schopný to pochopit a nakonec to dáš.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 23:15:08
Definuj korektní kód. Závisí ten můj kód někde na undefined behavior? Nezávisí.
Závisí. Máš tam logický vztah "bottom -> není dělitelné". Bottom je non-observable, tak by ses k tomu tak měl chovat
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 29. 08. 2018, 23:18:38
nevím, jestli jsi měl někde vyčíslitelnost, ale v principu pokud částečně rekurzivní funkce buď vrátí hodnotu nebo ji nevrátí - což v podstatě znamená, že se zacyklí. To je samozřejmě z hlediska programování blbý
Proto je lepší používat totality checking.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:19:28
Závisí. Máš tam logický vztah "bottom -> není dělitelné". Bottom je non-observable, tak by ses k tomu tak měl chovat
To není undefined behavior. Jen jsem zadefinoval, že případ dělení se řeší voláním error a error má definované chování. V Haskellu error observable je, jak jsi sám postoval před chvíli: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Je to prasárna, ale není to undefined.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 23:27:01
Závisí. Máš tam logický vztah "bottom -> není dělitelné". Bottom je non-observable, tak by ses k tomu tak měl chovat
To není undefined behavior. Jen jsem zadefinoval, že případ dělení se řeší voláním error a error má definované chování. V Haskellu error observable je, jak jsi sám postoval před chvíli: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Je to prasárna, ale není to undefined.

https://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Err.html#undefined (https://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Err.html#undefined)
Kód: [Vybrat]
undefined :: forall (r :: RuntimeRep). forall (a :: TYPE r).
             HasCallStack => a
undefined =  error "Prelude.undefined"
Je. A tohle není hříčka, to je míněno naprosto vážně.

Myslím, že tady platí velmi trefná poznámka od JSH: ty si myslíš, že ten kód se vykonává a má chování. Jenomže ono to tak není.... Ty v podstatě v tom kódu popisuješ, jak vypadá výsledek. A odvozuješ to z "bottom". Což prostě nejde.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 23:28:03
Závisí ten můj kód někde na undefined behavior? Nezávisí.

Závisí na tom, že spadne.

Dělá věci tak, jak by se normálně dělat měly? Nedělá.

Aspoň že se přiznáš.

Může reálně nastat, že někoho napadne udělat podobnou věc? Může.

To není argument.

Zaručuje Haskell, že výsledek strict a lazy vyhodnocení bude stejný? Nezaručuje.

O tomto nikdo nemluví (a není to ani otázka Haskellu). Řeč byla o tom, že kód napsaný v Haskellu striktně (ne)pojede v lazy.

Musím se rozdíly mezi strict a lazy vyhodnocením zabývat, když chci ho převzít cizí kód? Musím, protože se nemůžu spoléhat na to, že někdo nevymyslí podobnou prasárnu.

A ty přebíráš někdy kód bez toho, aniž by ses podíval, co přebíráš?  :o
Jinak sorry, ale to není argument, stejně můžu napsat: Musím se zabývat tím, co je a co není "undefined behavior" v C, když chci převzít cizí kód? Musím, protože...

Máš ještě v něčem zmatek a potřebuješ to dále vysvětlit? Rád ti pomohu. Mám docela trpělivost a věřím, že jsi schopný to pochopit a nakonec to dáš.

Jo, rád bych věděl, jestli jen trollíš, nebo jo...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 29. 08. 2018, 23:30:40
Závisí. Máš tam logický vztah "bottom -> není dělitelné". Bottom je non-observable, tak by ses k tomu tak měl chovat
To není undefined behavior. Jen jsem zadefinoval, že případ dělení se řeší voláním error a error má definované chování. V Haskellu error observable je, jak jsi sám postoval před chvíli: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Je to prasárna, ale není to undefined.

Zase si pleteš pojmy a dojmy? Možná si přečti, co se ti tu snažíme celou dobu vysvětlit...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:31:37
Myslím, že tady platí velmi trefná poznámka od JSH: ty si myslíš, že ten kód se vykonává a má chování. Jenomže ono to tak není.... Ty v podstatě v tom kódu popisuješ, jak vypadá výsledek. A odvozuješ to z "bottom". Což prostě nejde.
Ale ano jde, protože: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Pokud by tohle neplatilo, tak výsledek odvozovat nemůžu. Ale ono to platí. Takže výsledek můžu odvozovat od toho, jestli program vrátil operačnímu systému chybu, nebo ne.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 23:34:32
Myslím, že tady platí velmi trefná poznámka od JSH: ty si myslíš, že ten kód se vykonává a má chování. Jenomže ono to tak není.... Ty v podstatě v tom kódu popisuješ, jak vypadá výsledek. A odvozuješ to z "bottom". Což prostě nejde.
Ale ano jde, protože: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Pokud by tohle neplatilo, tak výsledek odvozovat nemůžu. Ale ono to platí. Takže výsledek můžu odvozovat od toho, jestli program vrátil operačnímu systému chybu, nebo ne.
Nemůžeš. Haskell je postavený principiálně na denotational semantics, nikoliv operational semantics. Jinak pochopils, že to co děláš je fakt undefined?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:37:09
Závisí na tom, že spadne.
Definuj spadne.

Může reálně nastat, že někoho napadne udělat podobnou věc? Může.

To není argument.
To je velmi silný argument. Nevím, jestli jsi někdy vyvíjel v týmu nebo přebíral cizí kód. Opravdu by ses divil, co se dá vymyslet za prasárny.

Zaručuje Haskell, že výsledek strict a lazy vyhodnocení bude stejný? Nezaručuje.

O tomto nikdo nemluví (a není to ani otázka Haskellu). Řeč byla o tom, že kód napsaný v Haskellu striktně (ne)pojede v lazy.
Težko se s tebou bavit, když používáš termíny jako nepojede. Pod tím si můžeš představit cokoliv. Máš nějaké předpoklady o výstupu a tomu skutečný výstup buď opovídá, nebo ne.

Musím se rozdíly mezi strict a lazy vyhodnocením zabývat, když chci ho převzít cizí kód? Musím, protože se nemůžu spoléhat na to, že někdo nevymyslí podobnou prasárnu.

A ty přebíráš někdy kód bez toho, aniž by ses podíval, co přebíráš?  :o
Jinak sorry, ale to není argument, stejně můžu napsat: Musím se zabývat tím, co je a co není "undefined behavior" v C, když chci převzít cizí kód? Musím, protože...
Samozřejmě se musíš zabývat undefined behavior v C, stejně jako se musíš zabývat rozdíly strict versus lazy vyhodnocení v Haskellu, to je jasná věc.

Jo, rád bych věděl, jestli jen trollíš, nebo jo...
Tady trolí úplně všichni.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:38:58
Nemůžeš. Haskell je postavený principiálně na denotational semantics, nikoliv operational semantics. Jinak pochopils, že to co děláš je fakt undefined?
Já se klidně nechám přesvědčit, že je to undefined, prosím tedy něco z Haskell reportu, co popírá tuhle větu: A call to error terminates execution of the program and returns an appropriate error indication to the operating system.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 29. 08. 2018, 23:45:27
Nemůžeš. Haskell je postavený principiálně na denotational semantics, nikoliv operational semantics. Jinak pochopils, že to co děláš je fakt undefined?
Já se klidně nechám přesvědčit, že je to undefined, prosím tedy něco z Haskell reportu, co popírá tuhle větu: A call to error terminates execution of the program and returns an appropriate error indication to the operating system.
Ale ono ji nic nepopírá. Jenom je irelevantní. Haskellový kód by měl být interpretován podle principů "denotational semantics". Viz. https://en.wikibooks.org/wiki/Haskell/Denotational_semantics (https://en.wikibooks.org/wiki/Haskell/Denotational_semantics). Ta věta výše popisuje operational semantics, což je vzhledem k sémantice kódu irelevantní. Prostě ten tvůj kód podle denotational semantics netestuje dělitelnost nulou, jenom to tak podle operational semantics většinou vyjde.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 29. 08. 2018, 23:52:55
Ale ono ji nic nepopírá. Jenom je irelevantní. Haskellový kód by měl být interpretován podle principů "denotational semantics". Viz. https://en.wikibooks.org/wiki/Haskell/Denotational_semantics (https://en.wikibooks.org/wiki/Haskell/Denotational_semantics). Ta věta výše popisuje operational semantics, což je vzhledem k sémantice kódu irelevantní. Prostě ten tvůj kód podle denotational semantics netestuje dělitelnost nulou, jenom to tak podle operational semantics většinou vyjde.
No a? Já říkám od začátku, že je to prasárna, ale není to undefined behavior. Haskell zaručuje, že ten program dává deterministické výsledky, protože chování error je jasně specifikované.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 00:14:05
Ale ono ji nic nepopírá. Jenom je irelevantní. Haskellový kód by měl být interpretován podle principů "denotational semantics". Viz. https://en.wikibooks.org/wiki/Haskell/Denotational_semantics (https://en.wikibooks.org/wiki/Haskell/Denotational_semantics). Ta věta výše popisuje operational semantics, což je vzhledem k sémantice kódu irelevantní. Prostě ten tvůj kód podle denotational semantics netestuje dělitelnost nulou, jenom to tak podle operational semantics většinou vyjde.
No a? Já říkám od začátku, že je to prasárna, ale není to undefined behavior. Haskell zaručuje, že ten program dává deterministické výsledky, protože chování error je jasně specifikované.
Chování error je isomorfní s chováním undefined, viz ta definice undefined výše. Takže to je undefined.... No a v případě haskellových programů se o "behaviour" moc nebavíme, protože "behaviour" je typické pro operational semantics, nikoliv pro denotational semantics, tam žádné není...

Vzhledem k tomu, že sis ten text nepřečetl, tak ti to shrnu: haskellové programy se interpretují jako matematická rovnice. To, co jsi napsal, není vyjádřením testu na to, zda lze dělit to číslo nulou. Je to nedefinované, protože bottom je synonymomum pro nedefinovanou hodnotu a z toho nemůžeš nic odvodit. Nicméně, překladač haskellu pracuje deterministicky, dokonce jsi použil jenom instrukce popsané ve specifikaci, a následně z tvého nedefinovaného výsledku deterministicky vygeneruje kód, který "shodou okolností" vrací korektní výsledky.

Ovšem nemůžeš se pak divit, že při nějaké změně sémantiky (strikt -> lazy), která nemá na korektně napsané programy vliv, přestane ten tvůj chybný kód fungovat.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 00:22:31
Možná bych to shrnul takhle: tvůj kód uprostřed závisí na hodnotě undefined (to je ten error, bottom). Základní logické pravidlo říká "ex falso quod libet", aneb jakýkoliv výstup tvého programu je "správný". Takže ho nelze rozbít...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 00:32:54
Nicméně, překladač haskellu pracuje deterministicky, dokonce jsi použil jenom instrukce popsané ve specifikaci, a následně z tvého nedefinovaného výsledku deterministicky vygeneruje kód, který "shodou okolností" vrací korektní výsledky.
Ale to není shodou okolností. Je ZARUČENO, že ten kód dává korektní výsledky (ve smyslu deterministické). Zaručeno je to chováním volání error, jak je popsáno v Haskell specifikaci. Je úplně jedno, jak je error v Haskellu interně implemetovaný a jestli to má něco společného s bottom, protože na interní implementaci error výsledky mého programu vůbec nezávisí. Závisí pouze na popisu chování error podle Haskell specifikace.

Ovšem nemůžeš se pak divit, že při nějaké změně sémantiky (strikt -> lazy), která nemá na korektně napsané programy vliv, přestane ten tvůj chybný kód fungovat.
Já se nedivím. Jenom bych se vyvaroval termínů jako korektně napsané (to znamená podle nějakých zvyklostí, nebo nezávisející na nespecifikovaném chování) a chybný kód (chybný protože se to tak obvykle nedělá, nebo chybný protože z definice nemůže fungovat).
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 00:37:15
Já se nedivím. Jenom bych se vyvaroval termínů jako korektně napsané (to znamená podle nějakých zvyklostí, nebo nezávisející na nespecifikovaném chování) a chybný kód (chybný protože se to tak obvykle nedělá, nebo chybný protože z definice nemůže fungovat).
Tak ještě jednou: haskell je postavený na denotational semantics. Takže se ptáme, jaký význam má ten kód na základě nějakého "matematického" smyslu. Tvůj kód nemá význam testu na dělitelnost nulou(? nebude teď hledat). Význam tvého kódu není definovaný, protože má uprostřed bottom. Takže všechny ty výstupy, které jsi prezentoval, jsou správné.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 00:58:03
Tak ještě jednou: haskell je postavený na denotational semantics. Takže se ptáme, jaký význam má ten kód na základě nějakého "matematického" smyslu.
Jak do denotational semantics zapadá error v Haskellu? Je definovaný jako bottom. Jenomže na tom můj kód vůbec nezávisí. Závisí na konkrétní implementaci chování volání error v Haskellu. Tím chci říct, že se zabýváš věcmi, které jsou irelevantní. Je úplně jedno, že error je bottom. Ten kód závisí jen na chování volání error, jak je popsáno ve specifikaci Haskellu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 30. 08. 2018, 07:12:42
Závisí na tom, že spadne.
Definuj spadne.

Jako vážně?

Může reálně nastat, že někoho napadne udělat podobnou věc? Může.

To není argument.
To je velmi silný argument. Nevím, jestli jsi někdy vyvíjel v týmu nebo přebíral cizí kód. Opravdu by ses divil, co se dá vymyslet za prasárny.

Jenže s takovým přístupem se dá zneužít cokoliv, tudíž je irelevantní na tom stavět kritiku. Židle je špatná, protože někoho může napadnout s ní mlátit lidi... úplně stejně validní.

Zaručuje Haskell, že výsledek strict a lazy vyhodnocení bude stejný? Nezaručuje.

O tomto nikdo nemluví (a není to ani otázka Haskellu). Řeč byla o tom, že kód napsaný v Haskellu striktně (ne)pojede v lazy.
Težko se s tebou bavit, když používáš termíny jako nepojede. Pod tím si můžeš představit cokoliv. Máš nějaké předpoklady o výstupu a tomu skutečný výstup buď opovídá, nebo ne.

Nepojede - nebude fungovat, v tomto kontextu. Zatím jsme se dostali jen k ukázkám kódu, které jsouna úrovni dereference NULL pointeru v C. Teď už jen abys to pochopil...

Musím se rozdíly mezi strict a lazy vyhodnocením zabývat, když chci ho převzít cizí kód? Musím, protože se nemůžu spoléhat na to, že někdo nevymyslí podobnou prasárnu.

A ty přebíráš někdy kód bez toho, aniž by ses podíval, co přebíráš?  :o
Jinak sorry, ale to není argument, stejně můžu napsat: Musím se zabývat tím, co je a co není "undefined behavior" v C, když chci převzít cizí kód? Musím, protože...
Samozřejmě se musíš zabývat undefined behavior v C, stejně jako se musíš zabývat rozdíly strict versus lazy vyhodnocení v Haskellu, to je jasná věc.

Takže jsme došli k tomu, jak validní argument to byl... pěkné :)

Jo, rád bych věděl, jestli jen trollíš, nebo jo...
Tady trolí úplně všichni.

Ne, kupodivu jsou tu i tací, co se snaží pomáhat nebo diskutovat... :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 07:32:25
Tak ještě jednou: haskell je postavený na denotational semantics. Takže se ptáme, jaký význam má ten kód na základě nějakého "matematického" smyslu.
Jak do denotational semantics zapadá error v Haskellu? Je definovaný jako bottom. Jenomže na tom můj kód vůbec nezávisí. Závisí na konkrétní implementaci chování volání error v Haskellu. Tím chci říct, že se zabýváš věcmi, které jsou irelevantní. Je úplně jedno, že error je bottom. Ten kód závisí jen na chování volání error, jak je popsáno ve specifikaci Haskellu.
No vždyť jo. Psal jsi, že může odstranění XStrict ten tvůj rozbít. Nemůže, protože všechny výstupy, které jsi poskytl, jsou správné. Tvoje zadání umožňuje více různých výsledků.
Ano, všechny ty výstupy odpovídají specifikaci haskellu a chování error.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 07:52:11
Znáš tohle?
Kód: [Vybrat]
x = y.
Then x2 = xy.
Subtract the same thing from both sides:
x2 - y2 = xy - y2.
Dividing by (x-y), obtain
x + y = y.
Since x = y, we see that
2 y = y.
Thus 2 = 1, since we started with y nonzero.
Subtracting 1 from both sides,
1 = 0
Tak to je tvůj kód. Když se v kódu vyskytne undefined (tady dělení nulou), tak výsledek může být cokoliv. No a Haskell má volnost v tom, co si s tím kódem může dělat, pokud jsou ty operace ekvivalentní. Přechod Strict -> Lazy jsou všechno operace, které nemění výsledek. Takže všechny ty výsledky, které jsi psal - jsou správné. Odpovídají zadání, které jsi vyjádřil tím zdrojovým kódem.  Že to umožňuje víc správných výsledků? Jo, přesně tak jsi to zadal. Rozbije to Strict -> Lazy? Ne, jenom ti vrátí druhý možný výsledek.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 09:08:50
Takže všechny ty výsledky, které jsi psal - jsou správné. Odpovídají zadání, které jsi vyjádřil tím zdrojovým kódem.  Že to umožňuje víc správných výsledků? Jo, přesně tak jsi to zadal. Rozbije to Strict -> Lazy? Ne, jenom ti vrátí druhý možný výsledek.
S tím naprosto souhlasím. Můj program dává deterministické výsledky, které se liší podle strict/lazy vyhodnocení. Je záměrně tak napsaný. To už je problém uživatele, že za správnou považuje jen tu strict variantu, i když obě dělají přesně to, co dělat mají. On totiž výsledek interpretuje až uživatel, z hlediska vykonávání programu je výsledek vždy správný, pokud nebudeme uvažovat chyby překladače apod.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 30. 08. 2018, 10:05:53
Takže všechny ty výsledky, které jsi psal - jsou správné. Odpovídají zadání, které jsi vyjádřil tím zdrojovým kódem.  Že to umožňuje víc správných výsledků? Jo, přesně tak jsi to zadal. Rozbije to Strict -> Lazy? Ne, jenom ti vrátí druhý možný výsledek.
S tím naprosto souhlasím. Můj program dává deterministické výsledky, které se liší podle strict/lazy vyhodnocení. Je záměrně tak napsaný. To už je problém uživatele, že za správnou považuje jen tu strict variantu, i když obě dělají přesně to, co dělat mají. On totiž výsledek interpretuje až uživatel, z hlediska vykonávání programu je výsledek vždy správný, pokud nebudeme uvažovat chyby překladače apod.
Ehm... Tohle myslíš vážně? error znamená, že je program rozjebaný tak, že se nedá mluvit o normálních hodnotách. error je jedna z mála funkcí, které jsou specifikované jenom neformálním pokecem, protože je to funkce pro případ, že je všechno totálně v zadeki.
Opravdu existuje uživatel, který interpretuje něco takového jako správnou variantu? To jsi mu musel nakecat pěkné hovadiny.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 10:19:41
Ehm... Tohle myslíš vážně? error znamená, že je program rozjebaný tak, že se nedá mluvit o normálních hodnotách. error je jedna z mála funkcí, které jsou specifikované jenom neformálním pokecem, protože je to funkce pro případ, že je všechno totálně v zadeki.
Opravdu existuje uživatel, který interpretuje něco takového jako správnou variantu? To jsi mu musel nakecat pěkné hovadiny.
Nerozumíš psanému textu. Já mluvím o uživateli, který interpretuje výstup programu. Tomu je interní implementace ukradená. Zajímáho ho, jestli program dává správné výsledky dle jeho požadavků. Jestli je uvnitř programu error, nebo tisk výsledku na tiskárně, odeslání poštovním holubem na centrálu, kontrola na centrále, odeslání poštovním holubem zpět, naskenování, OCR a až následně výstup k uživateli, nemá výsledek programu vliv. Je to interní implementace.

Error je jasně specifikovaný: https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Klíčové je: A call to error terminates execution of the program and returns an appropriate error indication to the operating system.
Je pravda, že to neodpovídá implementaci (protože error se dá chytit a tom specifikace nic neříká), ale s tím já už nic neudělám, to je problém Haskellu, že mají něco implementované jinak, než specifikované.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 10:32:22
S tím naprosto souhlasím. Můj program dává deterministické výsledky, které se liší podle strict/lazy vyhodnocení. Je záměrně tak napsaný. To už je problém uživatele, že za správnou považuje jen tu strict variantu, i když obě dělají přesně to, co dělat mají. On totiž výsledek interpretuje až uživatel, z hlediska vykonávání programu je výsledek vždy správný, pokud nebudeme uvažovat chyby překladače apod.
No tak to právě není. Ty máš nějak specifikované zadání, to zadání přetvoříš do zdrojového kódu. U jazyků postavených na operational semantics se ptáš "zdroják + operational spec == zadání"? U Haskell se ptáš "zdroják == zadání"? No, a to neplatí.

Zkusím vysvětlit ještě jinak - ty jsi tvrdil, že přechod Strict -> Lazy může ten program rozbít. Tak když to přirovnám k matematice, tak ten přechod je prostě nějaká transformace kódu. No a Strict -> Lazy je třeba jako aplikovat na obě strany rovnice exp(), a Lazy -> Strict je jako aplikovat na obě strany rovnice log(). log() to může rozbít, pokud by se tam vyskytne negativní číslo. exp() to nerozbije.

No, jenomže tvoje rovnice někde obsahuje dělení nulou a je undefined. Což je za normálních okolností crash. Jenomže ten stroj jménem překladač to i tak začne podle Operational semantics vyhodnocovat (úplně stejně, jako je ten postup v tom příkladu výše), a pak samozřejmě dojde k nějakým výsledkům - třeba, že 0=1. nebo 0=10. Nebo 5=5. A ty sis zrovna vybral 5=5 a tváříš se, že program "funguje". A pak aplikuješ nějakou pragmu a on podle toho nedefinovaného zadání dojde k 0=1. Jenomže na základě zadání, které jsi mu dal, je tohle něco, k čemu klidně může aplikací standardních pravidel dojít.

Kokrektní program přechodem Strict->Lazy nerozbiješ - stejně jako žádnou rovnici "nerozbiješ", když na obě strany aplikuješ exp() (v R). Ale když aplikuješ log(), tak to rozbít můžeš, stejně jako při přechodu Lazy->Strict.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 30. 08. 2018, 10:32:35
Ehm... Tohle myslíš vážně? error znamená, že je program rozjebaný tak, že se nedá mluvit o normálních hodnotách. error je jedna z mála funkcí, které jsou specifikované jenom neformálním pokecem, protože je to funkce pro případ, že je všechno totálně v zadeki.
Opravdu existuje uživatel, který interpretuje něco takového jako správnou variantu? To jsi mu musel nakecat pěkné hovadiny.
Nerozumíš psanému textu. Já mluvím o uživateli, který interpretuje výstup programu. Tomu je interní implementace ukradená. Zajímáho ho, jestli program dává správné výsledky dle jeho požadavků. Jestli je uvnitř programu error, nebo tisk výsledku na tiskárně, odeslání poštovním holubem na centrálu, kontrola na centrále, odeslání poštovním holubem zpět, naskenování, OCR a až následně výstup k uživateli, nemá výsledek programu vliv. Je to interní implementace.
Pád programu není výstup, natož správný. error je něco na úrovni dialogového okna "Program provedl nepovolenou operaci" nebo assert(false). Pokud tvůj program dojde k erroru, tak v něm máš bug.
Citace
Error je jasně specifikovaný: https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Klíčové je: A call to error terminates execution of the program and returns an appropriate error indication to the operating system.
Je pravda, že to neodpovídá implementaci (protože error se dá chytit a tom specifikace nic neříká), ale s tím já už nic neudělám, to je problém Haskellu, že mají něco implementované jinak, než specifikované.
Error je specifikovaný úplně jinak, než normální čisté Haskellové funkce. Ty totiž nemají _chování_ ale _hodnotu_ pro nějaké vstupy. Nemůžeš o Haskellu přemýšlet imperativně. Ten jazyk funguje jinak.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: v 30. 08. 2018, 10:40:35
https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Citace
The actual program behavior when an error occurs is up to the implementation.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 10:56:48
https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1
Citace
The actual program behavior when an error occurs is up to the implementation.
Nejdřív si to celé přečti, než začneš vytrhávat věty z kontextu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 30. 08. 2018, 11:00:01
Je pravda, že to neodpovídá implementaci (protože error se dá chytit a tom specifikace nic neříká), ale s tím já už nic neudělám, to je problém Haskellu, že mají něco implementované jinak, než specifikované.
Chytit se dá i SIGSEGV, nebo panic v Rustu. Tak už to v prakticky používaných jazycích bývá, že tam jsou možnosti pro extrémně nepravděpodobné případy, kdy je třeba něco oprasit. Musím zdůrazňovat, že je to myšlené pro šílené situace a normálně to fakt není dobrý napad?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 11:04:06
Pád programu není výstup, natož správný. error je něco na úrovni dialogového okna "Program provedl nepovolenou operaci" nebo assert(false). Pokud tvůj program dojde k erroru, tak v něm máš bug.
Ten můj program je formálně správný. O žádný pád programu se nejedná. Využívá dokumentované chování volání error. Navíc Haskell implementuje error jako exception, která se dá chytit: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Exception.html#t:ErrorCall

Error je specifikovaný úplně jinak, než normální čisté Haskellové funkce. Ty totiž nemají _chování_ ale _hodnotu_ pro nějaké vstupy. Nemůžeš o Haskellu přemýšlet imperativně. Ten jazyk funguje jinak.
S tím souhlasím a po pravdě nechápu, proč v Haskellu error je. On tam totiž fakticky zavádí imperativní chování. Error do Haskellu vůbec nezapadá a dost ten jazyk rozbíjí.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 11:08:44
Chytit se dá i SIGSEGV
SIGSEGV je implementation defined, protože standard C neřeší, co se má stát při undefined behavior. Na chytání SIGSEGV se nemůžeš spoléhat.

Volání call v Haskellu není implementation defined, je jasně dané, co se stane: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. Ten můj program nezávisí na chytání error v Haskellu, funguje i bez catch, jen není tak elegantní. Závisí pouze na tom, že error přeruší běh programu, to je zaručeno.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 30. 08. 2018, 11:20:57
Pád programu není výstup, natož správný. error je něco na úrovni dialogového okna "Program provedl nepovolenou operaci" nebo assert(false). Pokud tvůj program dojde k erroru, tak v něm máš bug.
Ten můj program je formálně správný.
Není správný. To, že jsi došel k erroru znamená, že jsi někde porušil prerekvizitu funkce nebo nějaký invariant. A díky tomu už není vůbec možné vrátit výstup. Z pohledu sémantiky je error _bottom_. Že je z pohledu sémantiky error neodlišitelný od zacykleného výpočtu by ti mělo napovědět, že to ani náhodou není správně.
Citace
O žádný pád programu se nejedná. Využívá dokumentované chování volání error. Navíc Haskell implementuje error jako exception, která se dá chytit: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Exception.html#t:ErrorCall

Error je specifikovaný úplně jinak, než normální čisté Haskellové funkce. Ty totiž nemají _chování_ ale _hodnotu_ pro nějaké vstupy. Nemůžeš o Haskellu přemýšlet imperativně. Ten jazyk funguje jinak.
S tím souhlasím a po pravdě nechápu, proč v Haskellu error je. On tam totiž fakticky zavádí imperativní chování. Error do Haskellu vůbec nezapadá a dost ten jazyk rozbíjí.
Je to tam proto, že v praktických jazycích je fajn mít +- kontrolované řešení situací, kdy programátor něco sprasí tak, že u programu není vůbec možné přiřadit sémantiku podle specifikace jazyka. Není to dokonale blbuvzdorné, ale to není nic.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 11:47:14
Není správný. To, že jsi došel k erroru znamená, že jsi někde porušil prerekvizitu funkce nebo nějaký invariant. A díky tomu už není vůbec možné vrátit výstup. Z pohledu sémantiky je error _bottom_. Že je z pohledu sémantiky error neodlišitelný od zacykleného výpočtu by ti mělo napovědět, že to ani náhodou není správně.
Vycházíš z nesprávných předpokladů. Pro tebe je error _bottom_, ale reálně se chová jinak a je to dokumentované: A call to error terminates execution of the program. V Haskellu je error odlišitelný od _bottom_, protože je zaručeno, volání error není zacyklený výpočet.

Je to tam proto, že v praktických jazycích je fajn mít +- kontrolované řešení situací, kdy programátor něco sprasí tak, že u programu není vůbec možné přiřadit sémantiku podle specifikace jazyka. Není to dokonale blbuvzdorné, ale to není nic.
Tomu rozumím, ale je třeba domýšlet důsledy. Chápu praktické důvody, nicméně ve chvíli, kdy je error odlišitelný od _bottom_, což je a je to zaručeno, dá se zneužít k "imperativnímů" řízení toku programu.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 12:34:13
Pád programu není výstup, natož správný. error je něco na úrovni dialogového okna "Program provedl nepovolenou operaci" nebo assert(false). Pokud tvůj program dojde k erroru, tak v něm máš bug.
Ten můj program je formálně správný. O žádný pád programu se nejedná. Využívá dokumentované chování volání error. Navíc Haskell implementuje error jako exception, která se dá chytit: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Exception.html#t:ErrorCall
Pleteš si determinismus a formální správnost. To, že kompiler deterministicky převede "jakýkoliv", i formálně nesprávný, kód do něčeho co běží a dává "nějaké" výsledky neznamená, že tvůj kód je formálně správný.

Tvůj program je formálně správný stejně, jako je formálně správný důkaz, že 0=1. Všechny operace, které provádí, jsou přece formálně správné. Že tam někde uprostřed je dělení nulou? No a co, to, co následuje potom, je formálně správné...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 12:36:44
Tomu rozumím, ale je třeba domýšlet důsledy. Chápu praktické důvody, nicméně ve chvíli, kdy je error odlišitelný od _bottom_, což je a je to zaručeno, dá se zneužít k "imperativnímů" řízení toku programu.
V momentě, kdy máš v programu možnost psát ASM/FFI/etc., tak se to dá zneužít ke schození programu, měnění private proměnných, obcházení garancí jazyka....
C++ ti garantuje, že cizí objekt nemá přístup k private proměnným objektu jiného typu. Kecy. Stačí ASM. Negarantuje nic...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 13:00:53
V momentě, kdy máš v programu možnost psát ASM/FFI/etc., tak se to dá zneužít ke schození programu, měnění private proměnných, obcházení garancí jazyka....
C++ ti garantuje, že cizí objekt nemá přístup k private proměnným objektu jiného typu. Kecy. Stačí ASM. Negarantuje nic...
To je něco jiného, v případě volání ASM nemáš garantováno nic. Mně Haskell garantuje definované chování: A call to error terminates execution of the program. Jasně že je to zneužívání mechanismu reportu chyb k úplně jiným účelům, to nikdo nepopírá, nicméně není to obcházení garancí jazyka.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 13:18:59
V momentě, kdy máš v programu možnost psát ASM/FFI/etc., tak se to dá zneužít ke schození programu, měnění private proměnných, obcházení garancí jazyka....
C++ ti garantuje, že cizí objekt nemá přístup k private proměnným objektu jiného typu. Kecy. Stačí ASM. Negarantuje nic...
To je něco jiného, v případě volání ASM nemáš garantováno nic. Mně Haskell garantuje definované chování: A call to error terminates execution of the program. Jasně že je to zneužívání mechanismu reportu chyb k úplně jiným účelům, to nikdo nepopírá, nicméně není to obcházení garancí jazyka.
Garance jazyka platí pouze za předpokladu definovaných hodnot. Error je undefined, takže veškeré garance jazyka končí.
Přechod Strict -> Lazy provede nějakou transformaci kódu (odstranění seq). Jazyk garantuje, že tohle je ekvivalentní transformace. Ovšem pouze na definovaných hodnotách. Použitím error tuhle garanci zlikviduješ, takže to pak negarantuje nic.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 13:47:04
[Garance jazyka platí pouze za předpokladu definovaných hodnot. Error je undefined, takže veškeré garance jazyka končí.
Pořád vycházíš z chybného předpokladu, že volání error v Haskellu je bottom. Jenomže není, protože: A call to error terminates execution of the program.

Přechod Strict -> Lazy provede nějakou transformaci kódu (odstranění seq). Jazyk garantuje, že tohle je ekvivalentní transformace.
Jazyk to garantuje za předpokladu, že error je bottom. V Haskellu error není bottom.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 13:50:59
[Garance jazyka platí pouze za předpokladu definovaných hodnot. Error je undefined, takže veškeré garance jazyka končí.
Pořád vycházíš z chybného předpokladu, že volání error v Haskellu je bottom. Jenomže není, protože: A call to error terminates execution of the program.
To je popis chování, nikoliv hodnoty. Dobře, doména toho volání je Float+bottom. Když to není bottom, tak kolik to teda je?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 13:53:49
Jazyk to garantuje za předpokladu, že error je bottom. V Haskellu error není bottom.

Citace
Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination. Since Haskell is a non-strict language, all Haskell types include ⊥. That is, a value of any type may be bound to a computation that, when demanded, results in an error. When evaluated, errors cause immediate program termination and cannot be caught by the user. The Prelude provides two functions to directly cause such errors:

error     :: String -> a 
undefined :: a
Je.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 14:03:04
To je popis chování, nikoliv hodnoty.
Ano ten kód závisí na popisu chování.

Dobře, doména toho volání je Float+bottom. Když to není bottom, tak kolik to teda je?
Nevím. Doména toho volání je Float+bottom. A volání error dělá něco jiného... Neptej se mě proč, já chování error nedefinoval.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 14:06:57
Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination
Znovu opakuji, tohle v Haskellu neplatí. V Haskellu jde rozlišit volání error od non-termination protože: A call to error terminates execution of the program. Proto taky ten můj program může dělat všechny ty hnusné věci. Kdyby v Haskellu nešlo rozlišit volání error od bottom, potom by je dělat nemohl.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: JSH 30. 08. 2018, 14:22:20
Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination
Znovu opakuji, tohle v Haskellu neplatí. V Haskellu jde rozlišit volání error od non-termination protože: A call to error terminates execution of the program. Proto taky ten můj program může dělat všechny ty hnusné věci. Kdyby v Haskellu nešlo rozlišit volání error od bottom, potom by je dělat nemohl.
To byla citace z https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-230003.1

Opravdu trváš na tom, že to co se píše v dokumentaci v Haskellu neplatí?  ::)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 30. 08. 2018, 14:56:58
Tak teď jsem opravdu zvědavý na odpověď.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 30. 08. 2018, 18:41:57
Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination
Znovu opakuji, tohle v Haskellu neplatí. V Haskellu jde rozlišit volání error od non-termination protože: A call to error terminates execution of the program. Proto taky ten můj program může dělat všechny ty hnusné věci. Kdyby v Haskellu nešlo rozlišit volání error od bottom, potom by je dělat nemohl.
Čekáme na reakci, lopato.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 22:34:48
Dokumentace Haskellu je prostě nekonzistetní. Program v Haskellu může chytit ErrorCall exception a odlišit tak volání error od bottom. Když koukám na Control.Exception, tak jsou tam další zajímavé věci. Takže si asi dáme další nekonečné kolečko teoretizování o bottom a invariantnosti strict -> lazy transformace v Haskellu:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

main = catch
        (do
            putStrLn "Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo"
            input <- getLine
            let n = (read input :: Int)
            let a = div 1 n
            putStrLn "Tímto číslem lze dělit"
        )
        (\(err :: ArithException) -> putStrLn "Tímto číslem nelze dělit")

Strict:
Kód: [Vybrat]
ghc -O2 -XStrict test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
Tímto číslem nelze dělit

Lazy:
Kód: [Vybrat]
ghc -O2 test.hs
./test
Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo
0
Tímto číslem lze dělit
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 30. 08. 2018, 23:04:04
Ty s tím nedáš pokoj, i když ti tu bylo stokrát vysvětleno, v čem máš chybu?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 30. 08. 2018, 23:17:33
Ty s tím nedáš pokoj, i když ti tu bylo stokrát vysvětleno, v čem máš chybu?
Cikádo, já jsem prostě lopata. Mám problém, potřebuju vydělit čísla, jak to sakra udělám? Stack oveflow nikdy nezklame!
https://stackoverflow.com/questions/20822365/how-to-catch-a-divide-by-zero-error-in-haskell?answertab=votes#tab-top
Tak jsem to z toho slepil. Nemůže to být špatně, je to na stack overflow a má to 9 upvotes!
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 30. 08. 2018, 23:51:53
Dokumentace Haskellu je prostě nekonzistetní. Program v Haskellu může chytit ErrorCall exception a odlišit tak volání error od bottom.

Citace
Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination.

catch :: Exception e => IO a -> (e -> IO a) -> IO a
Pomohlo?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:00:20
Pomohlo?
Ne.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 00:06:32
Pomohlo?
Ne.
IO akce není "expression evaluation".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:08:31
IO akce není "expression evaluation".
A?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 00:09:58
IO akce není "expression evaluation".
A?
Že jsi schopen detekovat crash IO akce není v rozporu s tím, že "Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination.."
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:14:13
Že jsi schopen detekovat crash IO akce není v rozporu s tím, že "Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination.."
Ale já nedetekuju crash IO akce, já detekuju crash v dělení. Kde a jak to udělám je jedno, protože to co je v main včetně IO také spadá do definice "Haskell program".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 00:18:56
Že jsi schopen detekovat crash IO akce není v rozporu s tím, že "Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination.."
Ale já nedetekuju crash IO akce, já detekuju crash v dělení. Kde a jak to udělám je jedno, protože to co je v main včetně IO také spadá do definice "Haskell program".
To nejde. Podívej se na signature metody catch. To umí pouze detekovat výjimku, kterou vyvolá IO akce.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:28:02
Ale já nedetekuju crash IO akce, já detekuju crash v dělení. Kde a jak to udělám je jedno, protože to co je v main včetně IO také spadá do definice "Haskell program".
To nejde. Podívej se na signature metody catch. To umí pouze detekovat výjimku, kterou vyvolá IO akce.
Myslím, že slovíčkaříme. Expression evaluation (volání div) se děje uvnitř IO akce, nicméně ta věta: "Errors during expression evaluation, denoted by ⊥ (“bottom”), are indistinguishable by a Haskell program from non-termination" nic o IO akci neříká. Je úplně jedno, kde se expression evaluation děje.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 00:29:16
Já myslím, že ti není jasný, co se stane. Při vyhodnocování se celý ten do block v tom catch nejdřív vyhodnotí jako
Kód: [Vybrat]
undefined :: IO (). Tato akce se pokusí spustit, načež to celý crashne (v C bychom byli na úrovni SIGSEGV, pokus o spuštění kódu na adrese 0 apod.). Haskell ti teda umožní tohle chytit (signal handler na SIGSEGV v C taky existuje) a případně se podívat na nějaké informace, proč to crashlo (v C by sis mohl prohledat stack a zkusit odhadnout, co se asi tak stalo).
Jako jestli ti tohle připadá "jenom prasárna", tak bych tě nechtěl mít blízko svého kódu. Ty si doopravdy myslíš, že v jakémkoliv jazyce lze od překladač očekávat, že pro takovýhle kód bude cokoliv garantovat?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:35:53
Já myslím, že ti není jasný, co se stane. Při vyhodnocování se celý ten do block v tom catch nejdřív vyhodnotí jako
Kód: [Vybrat]
undefined :: IO ()
Která verze? Ta s error nebo nebo bez něj? Verze bez erroru vyhodí ArithException. Ale ono je to celkem jedno, nejde to srovnávat se SIGSEGV, protože SIGSEGV je undefined behavior a chytání SIGSEGV je implementation depended. Zpracování výjimek v Haskellu není implementation dependent, tam je jasně garantované, co se stane.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 00:40:50
Já myslím, že ti není jasný, co se stane. Při vyhodnocování se celý ten do block v tom catch nejdřív vyhodnotí jako
Kód: [Vybrat]
undefined :: IO ()
Která verze? Ta s error nebo nebo bez něj? Verze bez erroru vyhodí ArithException. Ale ono je to celkem jedno, nejde to srovnávat se SIGSEGV, protože SIGSEGV je undefined behavior a chytání SIGSEGV je implementation depended. Zpracování výjimek v Haskellu není implementation dependent, tam je jasně garantované, co se stane.
To je jedno, která. Tohle:
Kód: [Vybrat]
do
  let a = 6 /0
  putStrLn "Jde delit nulou"
[code]
znamená:
[code]
 let a = 6 /0
 in a `seq` putStrLn "Jde delit nulou

6/0 se vyhodnotí jako bottom, tím pádem a se vyhodnotí na bottom, bottom `seq` x = bottom, takže celý tenhle blok vyjde jako:

undefined :: IO ()
No a to se následně pokusíš spustit. Prostě takové:
Kód: [Vybrat]
NULL();

Citace
Ale ono je to celkem jedno, nejde to srovnávat se SIGSEGV, protože SIGSEGV je undefined behavior a chytání SIGSEGV je implementation depended.
Chceš tím naznačit, že kdyby chytání SIGSEGV bylo standardizované, že by to byl korektní způsob programování a samozřejmě bys očekával veškeré garance překladače....??
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 00:50:40
Chceš tím naznačit, že kdyby chytání SIGSEGV bylo standardizované, že by to byl korektní způsob programování a samozřejmě bys očekával veškeré garance překladače....??
Já tu otázku s dovolením otočím. Chceš snad naznačit, že překladač Haskellu nic negarantuje a nezpracuje správně kód, který není unsafe a nezávisí na undefined behavior? To je úplně stejná demagogie, jakou jsi předvedl. Takže bych sem znovu s dovolením dal kód a rád bych od tebe věděl, jesti je v rozporu s něčím v Haskell language report a jestli bude dávat deterministický výstup ve strict i v lazy variantě:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

main = catch
        (do
            putStrLn "Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo"
            input <- getLine
            let n = (read input :: Int)
            let a = div 1 n
            putStrLn "Tímto číslem lze dělit"
        )
        (\(err :: ArithException) -> putStrLn "Tímto číslem nelze dělit")
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 01:03:19
Chceš tím naznačit, že kdyby chytání SIGSEGV bylo standardizované, že by to byl korektní způsob programování a samozřejmě bys očekával veškeré garance překladače....??
Já tu otázku s dovolením otočím. Chceš snad naznačit, že překladač Haskellu nic negarantuje a nezpracuje správně kód, který není unsafe a nezávisí na undefined behavior? To je úplně stejná demagogie, jakou jsi předvedl.
Tak to mi budeš muset vysvětlit. Řekl jsi:
Citace
Ale ono je to celkem jedno, nejde to srovnávat se SIGSEGV, protože SIGSEGV je undefined behavior a chytání SIGSEGV je implementation depended.
Takže pokud ti rozumím dobře, pokud by SIGSEGV bylo standardizované a chovalo se všude stejně, tak by to srovnávat šlo. Vzhledem k tomu, že požaduješ po haskellu v dané situaci, aby něco garantoval, tak když je to srovnatelné, tak bych očekával, že budeš to samé očekávat od C(++). Vzhledem k tomu, že volání "undefined" a chytání výjimky považuješ za normální, očekával bych, že budeš volání funkce na adrese 0 a chytání SIGSEGV považovat za normální.
Pokud tomu tak není, tak mi asi budeš muset vysvětlit, jak definuješ slovo "protože".

Citace
Takže bych sem znovu s dovolením dal kód a rád bych od tebe věděl, jesti je v rozporu s něčím v Haskell language report a jestli bude dávat deterministický výstup ve strict i v lazy variantě:
On ti dávat deterministický výstup bude, protože počítače jsou poněkud deterministické a pravidla pro vykonávání jsou celkem jasná. Bude ti dávat jiný výstup ve strict a lazy variantě. (nejsem si tím úplně 100% jistý, protože mi přijde, že by čistě teoreticky mohl optimalizátor ten let vyhodit, ale předpokládejme, že nemůže).

Tak. A původní otázka zněla, zda Strict->Lazy přechod může rozbít korektní haskellový program. Nikoliv, jestli je deterministický. Deterministický program může být pěkně nekorektní - viz tvůj příklad.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 01:13:57
A abych ti odpověděl na otázku, co je na tom programu nekorektní: při vstupu "0" se pokusí spustit IO akci "undefined". Což je paradoxně té adrese 0 dost podobné, protože tam taky "nic" není.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 01:22:23
Tak to mi budeš muset vysvětlit. Řekl jsi:
Citace
Ale ono je to celkem jedno, nejde to srovnávat se SIGSEGV, protože SIGSEGV je undefined behavior a chytání SIGSEGV je implementation depended.
Takže pokud ti rozumím dobře, pokud by SIGSEGV bylo standardizované a chovalo se všude stejně, tak by to srovnávat šlo. Vzhledem k tomu, že požaduješ po haskellu v dané situaci, aby něco garantoval, tak když je to srovnatelné, tak bych očekával, že budeš to samé očekávat od C(++). Vzhledem k tomu, že volání "undefined" a chytání výjimky považuješ za normální, očekával bych, že budeš volání funkce na adrese 0 a chytání SIGSEGV považovat za normální.
Pokud tomu tak není, tak mi asi budeš muset vysvětlit, jak definuješ slovo "protože".
Vysvětlím ti to. Vycházím z toho, co je ve standardu daného jazyka. Standard C SIGSEGV neřeší, je to undefined behavior. Haskell zpracování výjimek řeší, není to undefined behavior.

TL;DR
K tvojí otázce, jestli bych považoval chytání SIGSEGV za normální, tak ne. C je natolik nízkoúrovňové, že SIGSEGV v podstatě ani chytit nelze. Existují architektury, kde nemáš MMU a SIGSEGV nikdy nedostaneš. Program v C může do paměti přistupovat nekorektně a stejně SIGSEGV nedostane i na architekturách s MMU, pokud se zrovna trefí do svého paměťového rozsahu. Prakticky to prostě nejde udělat správně. SIGSEGV znamená pouze "teď už se to fakt posralo", ale neznamená to "předtím bylo všechno dobře a paměť je konzistentní". Takže když dostaneš SIGSEGV, nelze se spoléhat na to, že je paměť v konzistentním stavu (i když to v C vlastně nikdy...) a nelze se z toho nijak rozumně zotavit. Reálně se po SIGSEGV dají udělat jen dvě věci, uložit core dump pro pozdější analýzu nebo program rovnou ukončit, nic jiného nedává smysl.

On ti dávat deterministický výstup bude, protože počítače jsou poněkud deterministické a pravidla pro vykonávání jsou celkem jasná. Bude ti dávat jiný výstup ve strict a lazy variantě. (nejsem si tím úplně 100% jistý, protože mi přijde, že by čistě teoreticky mohl optimalizátor ten let vyhodit, ale předpokládejme, že nemůže).

Tak. A původní otázka zněla, zda Strict->Lazy přechod může rozbít korektní haskellový program. Nikoliv, jestli je deterministický. Deterministický program může být pěkně nekorektní - viz tvůj příklad.
Jestli je ten program korektní z hlediska výstupu, o tom nerozhoduješ ty, ale uživatel. Pokud uživatel potřebuje zjišťovat, zda lze zadaným číslem dělit, tak strict varianta mu dává korektní výsledky a lazy varianta nekorektní. Je to samozřejmě jen elementární příklad, takhle se je potřeba na něj dívat. Udělat v Haskellu podobně (uznávám podivně) řešení i jiných problémů, než dělení čísel, aby byly závislé na strict vyhodnocení, samozřejmě lze.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 01:26:25
A abych ti odpověděl na otázku, co je na tom programu nekorektní: při vstupu "0" se pokusí spustit IO akci "undefined". Což je paradoxně té adrese 0 dost podobné, protože tam taky "nic" není.
To je v rozporu s něčím v Haskell language report? Říká se tam, že se to nesmí dělat? Neříkám, že je to best practice, ale reálně to lidi (minimálně začátečníci) dělají: https://stackoverflow.com/questions/20822365/how-to-catch-a-divide-by-zero-error-in-haskell?answertab=votes#tab-top
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 01:49:59
Jestli je ten program korektní z hlediska výstupu, o tom nerozhoduješ ty, ale uživatel.
Tak to bude problém, protože my se tu nebavíme, zda je korektní z hlediska výstupů. Bavíme se o tom, jestli ten program jako takový dává smysl. Vrátím se k důkazu, že 0=1. Když vezmeš výsledek, vynásobíš obě strany 0 a přičteš 5, vyjde ti "5=5". A to je "korektní výstup". Ale celý ten důkaz je blbě.

Ty pořád přemýšlíš na úrovni "operational semantics" - mám tady interpret/překladač, a pokud program, který jsem do něj dal, používá pouze funkce dle specifikace a dává správné výsledky, pak je "korektní". Takže ten důkaz "5=5" by byl korektní.

Tenhle přístup se v haskellu vůbec nepoužívá. Je to funkcionální programování, celý program je zápis nějaké funkce, které vyjadřuje nějakou transformaci světa z jednoho stavu do jiného. A korektní program je takový, který je ekvivalentní specifikaci toho problému, který řešíš. V momentě, kdy se ti tam vyskytne "undefined", tak to není korektní. Ne, že by se občas takové programy nepsaly, ale prostě to není korektní a můžeš očekávat, že ti prostě jazyk v ten moment toho bude garantovat výrazně méně. Třeba ti přestane garantovat, že Strict -> Lazy transformace je ekvivalentní.

Mně celkem pobavilo, jak se strašně snažíš tvrdit, že to je "akademický jazyk" - ale pokud bys chtěl haskell mít v tomhle  akademický, tak bys tam měl typy bez bottom (přitom by to bylo lazy) a ty tvoje programy by tím vůbec neprošly. Jenomže takovéhle jazyky jsou strašně těžko použitelné (protože programátor musí dokazovat, že jsou všechny funkce totální). Takže v Haskellu to dokazovat nemusíš, typy obsahují bottom, ale když se ti tam nějaký bottom dostane, tak neseš následky. Deterministické následky, ale ten tvůj program pak prostě není korektní.

Citace
To je v rozporu s něčím v Haskell language report? Říká se tam, že se to nesmí dělat? Neříkám, že je to best practice, ale reálně to lidi (minimálně začátečníci) dělají: https://stackoverflow.com/questions/20822365/how-to-catch-a-divide-by-zero-error-in-haskell?answertab=votes#tab-top
V rozporu? Ne. Jenom to není korektní program. Ten příklad ze stackoverflow je v pohodě - něco zkusil provést a slítlo to. Rozbitý program, informujeme uživatele, že to celý upadlo a proč. Nikdo se netváří, že to funguje korektně. Pro některé typy programů je to zcela dostačující, nevadí, že to crashne na vadném vstupu. Ale nikdo se taky netváří, že v takovém případě program pracuje korektně. Což je to, co tvrdíš ty.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 02:17:37
Citace
To je v rozporu s něčím v Haskell language report? Říká se tam, že se to nesmí dělat? Neříkám, že je to best practice, ale reálně to lidi (minimálně začátečníci) dělají: https://stackoverflow.com/questions/20822365/how-to-catch-a-divide-by-zero-error-in-haskell?answertab=votes#tab-top
V rozporu? Ne. Jenom to není korektní program. Ten příklad ze stackoverflow je v pohodě - něco zkusil provést a slítlo to. Rozbitý program, informujeme uživatele, že to celý upadlo a proč. Nikdo se netváří, že to funguje korektně. Pro některé typy programů je to zcela dostačující, nevadí, že to crashne na vadném vstupu. Ale nikdo se taky netváří, že v takovém případě program pracuje korektně. Což je to, co tvrdíš ty.
Já už tomu rozumím. Ten program nesplňuje zásadní podmínku, není korektní podle TEBE. Nestačí, že splňuje všechno co splňovat má, odpovídá Haskell language report, nedělá nic unsafe, nezávisí na undefined nebo implementation behavior a funguje dle očekávání. To je málo. Navíc musí být korektní podle TEBE. Tak bohužel, program korektní podle TEBE si budeš muset napsat sám.

A jen pro inspiraci, abys nežil v představě, že řešíme nějaké silně nepravděpodobné a okrajové případy a v Haskellu se to "tak prostě nedělá a nikoho by to ani nenapadlo": https://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 07:39:12
Citace
To je v rozporu s něčím v Haskell language report? Říká se tam, že se to nesmí dělat? Neříkám, že je to best practice, ale reálně to lidi (minimálně začátečníci) dělají: https://stackoverflow.com/questions/20822365/how-to-catch-a-divide-by-zero-error-in-haskell?answertab=votes#tab-top
V rozporu? Ne. Jenom to není korektní program. Ten příklad ze stackoverflow je v pohodě - něco zkusil provést a slítlo to. Rozbitý program, informujeme uživatele, že to celý upadlo a proč. Nikdo se netváří, že to funguje korektně. Pro některé typy programů je to zcela dostačující, nevadí, že to crashne na vadném vstupu. Ale nikdo se taky netváří, že v takovém případě program pracuje korektně. Což je to, co tvrdíš ty.
Já už tomu rozumím. Ten program nesplňuje zásadní podmínku, není korektní podle TEBE. Nestačí, že splňuje všechno co splňovat má, odpovídá Haskell language report, nedělá nic unsafe, nezávisí na undefined nebo implementation behavior a funguje dle očekávání. To je málo. Navíc musí být korektní podle TEBE. Tak bohužel, program korektní podle TEBE si budeš muset napsat sám.
Ten důkaz 0=1 nesplňuje základní podmínku: Není korektní podle MĚ. Fakt?

Citace
A jen pro inspiraci, abys nežil v představě, že řešíme nějaké silně nepravděpodobné a okrajové případy a v Haskellu se to "tak prostě nedělá a nikoho by to ani nenapadlo": https://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
A odpověd:
Citace
error is supposed to be as observable as an infinite loop. You can only catch error in IO, which is like saying "yeah you can if you know magic". But from the really nice part of Haskell, pure code, it is unrecoverable, and thus it is strongly advised not to use in your code, only as much as you would ever use an infinite loop as an error code
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 31. 08. 2018, 08:50:14
Ten důkaz 0=1 nesplňuje základní podmínku: Není korektní podle MĚ. Fakt?
Ten tvůj “důkaz" je úplná blbost a nijak nesouvisí s chytání výjimky při dělení nulou v Haskellu. Nechápu, proč takové nesmysly píšeš?

Citace
A jen pro inspiraci, abys nežil v představě, že řešíme nějaké silně nepravděpodobné a okrajové případy a v Haskellu se to "tak prostě nedělá a nikoho by to ani nenapadlo": https://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
A odpověd:
Citace
error is supposed to be as observable as an infinite loop. You can only catch error in IO, which is like saying "yeah you can if you know magic". But from the really nice part of Haskell, pure code, it is unrecoverable, and thus it is strongly advised not to use in your code, only as much as you would ever use an infinite loop as an error code
U chytání error je to diskutabilní, ale u chytání aritmetické výjimky z div ne. To je prostě legitimní řešení problému. Možná to není best practice, ale je to korektní řešení. Nicméně to není pointa. Pointa je, že lidi takové věci v Haskellu dělají a dělat budou. Můžeš s tím nesouhlasit, můžeš proti tomu protestovat, ale to je asi tak jediné, co s tím můžeš dělat.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 09:30:58
Ten důkaz 0=1 nesplňuje základní podmínku: Není korektní podle MĚ. Fakt?
Ten tvůj “důkaz" je úplná blbost a nijak nesouvisí s chytání výjimky při dělení nulou v Haskellu. Nechápu, proč takové nesmysly píšeš?
Protože interpretace haskellového kódu je postavena na denotační sémantice, aneb očekává se, že to bude mít nějaký matematický smysl. Curry-howard isomorfismus je v haskell světě skloňováno docela často. Ne, že aplikace nějakých operačních pravidel k něčemu vede, a pokud ta pravidla byla aplikována správně, tak je výsledek korektní. Něco jako ten důkaz - slepě aplikuješ pravidla a ono to k něčemu vede. A ty se snažíš v podstatě říct, že pokud je výsledek správně, tak je ten předchozí postup správně.

Špatný důkaz neznamená, že závěr neplatí.  Klidně může, ale to neznamená, že ten důkaz je správně. Ano, haskellový program může vracet správné výsledky, protože se chová deterministicky. To neznamená, že ten kód dává nějaký smysl.


Citace
Citace
A jen pro inspiraci, abys nežil v představě, že řešíme nějaké silně nepravděpodobné a okrajové případy a v Haskellu se to "tak prostě nedělá a nikoho by to ani nenapadlo": https://stackoverflow.com/questions/4243117/how-to-catch-and-ignore-a-call-to-the-error-function
A odpověd:
Citace
error is supposed to be as observable as an infinite loop. You can only catch error in IO, which is like saying "yeah you can if you know magic". But from the really nice part of Haskell, pure code, it is unrecoverable, and thus it is strongly advised not to use in your code, only as much as you would ever use an infinite loop as an error code
U chytání error je to diskutabilní, ale u chytání aritmetické výjimky z div ne. To je prostě legitimní řešení problému.
V Haskellu není. Je to bottom, to je stejné jako error.

Citace
Možná to není best practice, ale je to korektní řešení. Nicméně to není pointa. Pointa je, že lidi takové věci v Haskellu dělají a dělat budou. Můžeš s tím nesouhlasit, můžeš proti tomu protestovat, ale to je asi tak jediné, co s tím můžeš dělat.
Vůbec netuším, co tím chceš říct. Že lidi budou psát zabugovaný kód? Který z nějakých důvodů dává správné výsledky, dokud se překladač nebo jiný programátor nerozhodne provést nějakou transformaci, která ten kód rozbije? No jasně...a?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 31. 08. 2018, 10:23:03
Ten důkaz 0=1 nesplňuje základní podmínku: Není korektní podle MĚ. Fakt?
Ten tvůj “důkaz" je úplná blbost a nijak nesouvisí s chytání výjimky při dělení nulou v Haskellu. Nechápu, proč takové nesmysly píšeš?

Právě že souvisí :) A až to pochopíš, tak taky pochopíš, proč celé vlákno píšeš kraviny. :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 31. 08. 2018, 12:24:08
Ten důkaz 0=1 nesplňuje základní podmínku: Není korektní podle MĚ. Fakt?
Ten tvůj “důkaz" je úplná blbost a nijak nesouvisí s chytání výjimky při dělení nulou v Haskellu. Nechápu, proč takové nesmysly píšeš?
Právě že souvisí :) A až to pochopíš, tak taky pochopíš, proč celé vlákno píšeš kraviny. :)
Když to nepochopil doteď, už to nepochopí nikdy.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 13:16:31
Já to zkusím ještě jinak.

Představ si třeba Javu. Je následující korektní kód?
Kód: [Vybrat]
int a = 3 + "test";Není. Proč? Protože ti nesedí typy. Teď si představ, že Java by měla switch, který vypne typovou konverzi, tohle se normálně zkompiluje a při běhu to vyhodí přesně specifikovanou výjimku. Stane se z toho korektní kód? Já bych řekl, že ne. Jenom prostě překladač v daném momentě není schopen/ochoten zkontrolovat, že ten kód, co jsi mu dal, je korektní a že je to blbě zjistí až při běhu.

Podobně máš třeba null pointer exception.
Kód: [Vybrat]
Object x = null; x.equals(x);Tohle taky není korektní kód, ale typovou kontrolou ti projde, protože typový systém Javy tohle není schopen při kompilaci odhalit. V kotlinu už ty typy postavili trošku jinak, a najednou to ten typový systém odhalí.

A teď k Haskellu: je to lazy jazyk, takže všechny typy obsahují bottom. -XStrict to de-fakto v rámci toho modulu přepneš do strikt sémantiky; takže v rámci toho modulu typy přestanou obsahovat bottom. Když pak uděláš nějakou funkci ve stylu:
Kód: [Vybrat]
f :: Int -> Int
f 0 = error "Chyba"
f x = x
Tak to je nekorektní kód, protože z funkce, která by měla vracet Int vracíš bottom (resp. do následující funkce, která očekává Int bez bottomu to dopluje). To je typová chyba, akorát to překladač není schopen to zkontrolovat (mimo jiné, protože to je obecně nerozhodnutelný problém), takže se spoléhá na to, že uživatel v tomhle nelže. Jsou jazyky, které jsou schopny v typovém systému řešit, jestli typ obsahuje bottom nebo ne, haskell to neumí.

Pokud jde o souvislost s důkazem: to je takový pěkný poznatek, že typový signature je "tvrzení" a implementace funcke je "důkaz". (https://wiki.haskell.org/Curry-Howard-Lambek_correspondence (https://wiki.haskell.org/Curry-Howard-Lambek_correspondence)). Pokud ti z implementace nic nevypadne (což je bottom - nekonečné zacyklení), tak jsi nic nedokázal. No a speciálně v tom Strict režimu je to úplně přesně jako to dělení 0 v tom důkazu 0=1. Ty mechanicky klidně můžeš pokračovat dál, interpret klidně mechanicky bude vykonávat ten kód podle nějakých pravidel, možná to i povede k nějakému korektnímu výsledku, ale to nic nemění na tom, že ten důkaz je blbě.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 31. 08. 2018, 13:17:37
Citace
Není. Proč? Protože ti nesedí typy. Teď si představ, že Java by měla switch, který vypne typovou konverzi kontrolu
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 09:15:23
Citace
Možná to není best practice, ale je to korektní řešení. Nicméně to není pointa. Pointa je, že lidi takové věci v Haskellu dělají a dělat budou. Můžeš s tím nesouhlasit, můžeš proti tomu protestovat, ale to je asi tak jediné, co s tím můžeš dělat.
Vůbec netuším, co tím chceš říct. Že lidi budou psát zabugovaný kód? Který z nějakých důvodů dává správné výsledky, dokud se překladač nebo jiný programátor nerozhodne provést nějakou transformaci, která ten kód rozbije? No jasně...a?

Pořád jsi to nepochopil, takže si dáme další kolečko.Ten kód:
Kód: [Vybrat]
{-# LANGUAGE ScopedTypeVariables #-}

import Control.Exception

main = catch
        (do
            putStrLn "Tento program zjišťuje, zda lze zadaným číslem dělit. Zadejte číslo"
            input <- getLine
            let n = (read input :: Int)
            let a = div 1 n
            putStrLn "Tímto číslem lze dělit"
        )
        (\(err :: ArithException) -> putStrLn "Tímto číslem nelze dělit")

NENÍ zabugovaný. Je GARANTOVÁNO, že bude při strict vyhodnocení fungovat správně. Pokud si myslíš opak, tak prosím exaktně řekni, co z Haskell language report porušuje. Nestačí říct, že se ti nelíbí. Chtěl jsi kód, který v Haskellu bude dávat jiné výsledky při strict a lazy vyhodnocení. Dostal jsi ho. A znovu opakuji, žádná chyba v něm není, při strict vyhodnocení má GARANTOVANÉ chování a dává správné výsledky.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 09:26:12
NENÍ zabugovaný. Je GARANTOVÁNO, že bude při strict vyhodnocení fungovat správně. Pokud si myslíš opak, tak prosím exaktně řekni, co z Haskell language report porušuje. Nestačí říct, že se ti nelíbí. Chtěl jsi kód, který v Haskellu bude dávat jiné výsledky při strict a lazy vyhodnocení. Dostal jsi ho. A znovu opakuji, žádná chyba v něm není, při strict vyhodnocení má GARANTOVANÉ chování a dává správné výsledky.
No Haskell report je z 2010, XStrict je tak rok starý...

Je v něm typová chyba: vrací se bottom tam, kde se očekává typ, který bottom neobsahuje. Haskell tento typ chyby není schopen odhalit při překladu, slítne to v runtimu.

Mně totiž připadá, že ty se snažíš tvrdit, že pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů, tak žádné nekorektní programy vlastně nejsou...?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 09:41:46
NENÍ zabugovaný. Je GARANTOVÁNO, že bude při strict vyhodnocení fungovat správně. Pokud si myslíš opak, tak prosím exaktně řekni, co z Haskell language report porušuje. Nestačí říct, že se ti nelíbí. Chtěl jsi kód, který v Haskellu bude dávat jiné výsledky při strict a lazy vyhodnocení. Dostal jsi ho. A znovu opakuji, žádná chyba v něm není, při strict vyhodnocení má GARANTOVANÉ chování a dává správné výsledky.
No Haskell report je z 2010, XStrict je tak rok starý...
To ale není můj problém...

Je v něm typová chyba: vrací se bottom tam, kde se očekává typ, který bottom neobsahuje. Haskell tento typ chyby není schopen odhalit při překladu, slítne to v runtimu.
Neslítne to. Haskell language report někde říká, že když se vrátí bottom, je to nedefinované chování? Neříká. Vyhodí to ArithException, která se dá chytit. Haskell to umožňuje a je to definované chování. Já chápu, že se ti nelíbí, jak je to udělané a že tu výjimku chytám. Mně se to taky nelíbí, dělám to z toho důvodu, protože jsi tvrdil, že v Haskellu nemůže existovat program, který závisí na strict vyhodnocení. Může.

Mně totiž připadá, že ty se snažíš tvrdit, že pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů, tak žádné nekorektní programy vlastně nejsou...?
To netvrdím. Nekorektní program je takový, který dává nedeterministické výsledky (ve smyslu, že závisí na undefined behavior a pak se může stát cokoliv) nebo program, který dává jiné než očekávané výsledky.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 09:53:09
Pokud si myslíš opak, tak prosím exaktně řekni, co z Haskell language report porušuje..
No Haskell report je z 2010, XStrict je tak rok starý...
To ale není můj problém...
No comment.

Citace
Je v něm typová chyba: vrací se bottom tam, kde se očekává typ, který bottom neobsahuje. Haskell tento typ chyby není schopen odhalit při překladu, slítne to v runtimu.
Neslítne to.
Slítne vyhodnocování výrazu, abych se vyjádřil úplně přesně. Je v něm v podstatě typová chyba, ale typový systém Haskellu není dostatečně silný, aby tohle byl schopen zachytit. Máš k tomu nějaký komentář?

Citace
Haskell language report někde říká, že když se vrátí bottom, je to nedefinované chování? Neříká.
Říká, že to je nedefinovaná hodnota. Haskell je funkcionální jazyk, pracujeme převážně s hodnotami. Pokus o vyhodnocení nedefinované hodnoty je nekorektní stav programu.

Citace
Vyhodí to ArithException, která se dá chytit. Haskell to umožňuje a je to definované chování. Já chápu, že se ti nelíbí, jak je to udělané a že tu výjimku chytám. Mně se to taky nelíbí, dělám to z toho důvodu, protože jsi tvrdil, že v Haskellu nemůže existovat program, který závisí na strict vyhodnocení. Může.
Je to nekorektní stav programu, který jsi schopen zachytit a zpracovat.

Citace
Mně totiž připadá, že ty se snažíš tvrdit, že pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů, tak žádné nekorektní programy vlastně nejsou...?
To netvrdím. Nekorektní program je takový, který dává nedeterministické výsledky (ve smyslu, že závisí na undefined behavior a pak se může stát cokoliv) nebo program, který dává jiné než očekávané výsledky.
Takže přesněji:

Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.

Souhlasíš s tím?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 09:59:27
Citace
dělám to z toho důvodu, protože jsi tvrdil, že v Haskellu nemůže existovat program, který závisí na strict vyhodnocení
A tak nějak už tady několik stránek řešíme, že v Haskellu nemůže existovat korektní program, který závisí na strict vyhodnocení. Zabugovaný program, který závisí na Strict vyhodnocení samozřejmě existovat může.... člověk by čekal, že těch pár stránek stačilo k tomu, abys to pochopil?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 10:46:04
Pokud si myslíš opak, tak prosím exaktně řekni, co z Haskell language report porušuje..
No Haskell report je z 2010, XStrict je tak rok starý...
To ale není můj problém...
No comment.
Mně by se taky líbilo, kdyby pro Haskell existovalo něco tak podrobného, jako ISO standard pro C, ale bohužel neexistuje.

Říká, že to je nedefinovaná hodnota. Haskell je funkcionální jazyk, pracujeme převážně s hodnotami. Pokus o vyhodnocení nedefinované hodnoty je nekorektní stav programu.
Výsledek operace div není pro některé hodnoty definován, v takovém případě funkce div vrací bottom type, v Haskellu konkrétně aritmetickou výjimku. Není to nekorektní stav programu, vrací se bottom type v případě, kdy se má vracet. Je naprosto v pořádku, že se vyhodí aritmetická výjimka. Ta výjimka se zachytí, zpracuje a výsledek operace dělení se prohlásí za neplatný. Nehledej v tom žádnou vědu. Nic nekorektního tam není, žádný nekorektní stav nenastává a výsledek všech operací je definovaný a garantovaný.

Takže přesněji:
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.

Souhlasíš s tím?
Nevymýšlej nesmysly. Jasně jsem napsal, že korektní program je jen takový, který dává očekávaný (ve smyslu správný) výstup.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 10:57:07
Citace
Říká, že to je nedefinovaná hodnota. Haskell je funkcionální jazyk, pracujeme převážně s hodnotami. Pokus o vyhodnocení nedefinované hodnoty je nekorektní stav programu.
Výsledek operace div není pro některé hodnoty definován, v takovém případě funkce div vrací bottom type, v Haskellu konkrétně aritmetickou výjimku.
Nevrací.

Citace
Není to nekorektní stav programu
Citace
Errors during expression evaluation, denoted by ⊥ (“bottom”),
Bottom je CHYBA. Nekorektní stav programu.

Citace
vrací se bottom type v případě, kdy se má vracet.
Bottom nejde vrátit. Bottom je chyba. Viz výše haskell report.

Citace
Je naprosto v pořádku, že se vyhodí aritmetická výjimka. Ta výjimka se zachytí, zpracuje a výsledek operace dělení se prohlásí za neplatný. Nehledej v tom žádnou vědu. Nic nekorektního tam není, žádný nekorektní stav nenastává a výsledek všech operací je definovaný a garantovaný.
Jak bys nazval "stuck" stav v expression evaluation? Nekorektní, chybný stav programu?

Citace
Takže přesněji:
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.
Souhlasíš s tím?
Nevymýšlej nesmysly. Jasně jsem napsal, že korektní program je jen takový, který dává očekávaný (ve smyslu správný) výstup.
Dobře, tak ještě jinak:

Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů, pak každý program, který neobsahuje konstrukce s nedefinovaným chováním a vrací požadované výsledky na požadované vstupy, je korektní?

Takhle s tím souhlasíš?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 11:06:09
Ale já se nebavím o bottom v Haskellu, já se bavím o bottom type: https://en.m.wikipedia.org/wiki/Bottom_type

V Haskellu je garantováno, že div vyhodí aritmetickou výjimku. Není to nekorektní stav. Výsledek operace není definovaný, proto to vyhazuje výjimku. Znovu opakuji, nehledej v tom žádnou vědu, výsledek toho programu je definovaný a garantovaný.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 11:15:19
Ale já se nebavím o bottom v Haskellu, já se bavím o bottom type: https://en.m.wikipedia.org/wiki/Bottom_type
Jak se vrací typ? Když už se něco vrací, tak je to hodnota, a podíváš-li se na první větu toho, co odkazuješ, tak je tam napsáno:
Citace
In type theory, a theory within mathematical logic, the bottom type is the type that has no values
Hodnotu typu bottom vrátit nejde, protože žádná taková neexistuje.

Citace
V Haskellu je garantováno, že div vyhodí aritmetickou výjimku. Není to nekorektní stav. Výsledek operace není definovaný, proto to vyhazuje výjimku. Znovu opakuji, nehledej v tom žádnou vědu, výsledek toho programu je definovaný a garantovaný.
V Haskellu je definované, že některé chybové stavy, pokud budou spuštěny v "sandboxu" jménem "catch" způsobí, že nespadne celý program, ale místo toho se spustí druhý parametr toho catche.

Ale pořád jsme se nedostali k tomu, co TY považuješ za korektní. Je to tohle?

Citace
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů, pak každý program, který neobsahuje konstrukce s nedefinovaným chováním a vrací požadované výsledky na požadované vstupy, je korektní.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 11:25:13
A pokud jde o termín "vrací", tak v haskellu se nevrací.  V haskellu se nějaká část výrazu vyhodnotí na něco jiného. Ale tak pro zjednodušení můžeme pojem "vrací" definovat jako "vyhodnotí se na hodnotu".
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 11:34:07
Ale pořád jsme se nedostali k tomu, co TY považuješ za korektní. Je to tohle?
Už jsem to psal. Korektní program je takový, který dává výstup dle pożadavků uživatele. Je úplně jedno, jak je interně implementovaný. Pokud je uživatel s výstupem spokojen a program je deterministický (ve smyslu nezávisí na undefined behavior), potom je korektní. Jestli máš jinou definici korektní, tak se asi neshodneme.

A máš pravdu, že ten můj program je uvnitř implementovaný divoce a závisí na tom, že div vyhazuje aritmetickou výjimku, ale to uživatele nezajímá. Všechno, co ten program dělá, je v Haskellu garantované, ten program nezávisí na ničem unsafe. Při strict vyhodnocení dává deterministické výsledky, se kterými je uživatel spokojen, je tedy korektní, dělá přesně to, co má dělat, dle požadavků uživatele.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 11:38:52
Ale pořád jsme se nedostali k tomu, co TY považuješ za korektní. Je to tohle?
Už jsem to psal. Korektní program je takový, který dává výstup dle pożadavků uživatele. Je úplně jedno, jak je interně implementovaný. Pokud je uživatel s výstupem spokojen a program je deterministický (ve smyslu nezávisí na undefined behavior), potom je korektní. Jestli máš jinou definici korektní, tak se asi neshodneme.
Evaluation error - odpověď na otázku "Je to tohle?" Obashuje možnosti ANO a NE....

Citace
A máš pravdu, že ten můj program je uvnitř implementovaný divoce a závisí na tom, že div vyhazuje aritmetickou výjimku, ale to uživatele nezajímá. Všechno, co ten program dělá, je v Haskellu garantované, ten program nezávisí na ničem unsafe. Při strict vyhodnocení dává deterministické výsledky, se kterými je uživatel spokojen, je tedy korektní, dělá přesně to, co má dělat, dle požadavků uživatele.
Při vyhodnocování toho programu se nám trošku přehřál reaktor. Ale nevadí, tepelné pojistky to zastavily, takže se ve výsledku nic nestalo. Program pracuje korektně...

Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 01. 09. 2018, 11:46:22
To co teď předvádíš, je demagogie. K žádnému přehřátí reaktoru ani ničemu podobnému nedochází. Já chápu, že se ti ten program nelíbí, mně taky ne. Ale to ho nedělá nekorektní. Uživatel potřebuje vědět, zda lze daným číslem dělit a ten program při strict vyhodnocení přesně plní jeho požadavky, je tedy korektní.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 16:37:11
To co teď předvádíš, je demagogie. K žádnému přehřátí reaktoru ani ničemu podobnému nedochází. Já chápu, že se ti ten program nelíbí, mně taky ne. Ale to ho nedělá nekorektní. Uživatel potřebuje vědět, zda lze daným číslem dělit a ten program při strict vyhodnocení přesně plní jeho požadavky, je tedy korektní.
Ne, reaktor se nepřehřál, teplotní pojistky to zastavily..takže program běžel korektně. Ne, program nespadnul, sandbox jménem "catch" zabránil zhroucenému evaluátoru, aby sundal celý program. Ne, z funkce nemůžeš "vrátit" bottom....

Jinak Undefined... ptal jsem se tě, zda souhlasíš s tou větou ohledně korektnosti a ... nedříve type error, jiná odpověď teď bottom.....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 01. 09. 2018, 18:59:41
A jinak ohledně korektnosti - ja následující program korektní? Když vypneš type-checking, tak jde přeložit:
Kód: [Vybrat]
import Control.Exception (catch, TypeError(..), evaluate, try)

message :: String
message = "hello" ++ (1 :: Int)
main = do
  res <- try (evaluate $ message `seq` message)
  case res of
      Left (TypeError msg) -> putStrLn "Presne tohle uzivatel ocekaval."
      Right s -> putStrLn s

Já bych řekl, že korektní není, protože specifikace říká něco o tom, že tam nesedí typy. Ale přesto je to chování naprosto deterministické a v dokumentaci popsané (taky nové, takže v dokumentaci GHC - ale popsané) a uživatel je spokojený. To, že specifikace některé typy programů nebo stavů považuje za chybné (třeba za tím účelem, aby pak Strict -> Lazy nic nerozbilo) vypadá, že je zcela irelevantní....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 02. 09. 2018, 00:00:34
Ne, reaktor se nepřehřál, teplotní pojistky to zastavily..takže program běžel korektně. Ne, program nespadnul, sandbox jménem "catch" zabránil zhroucenému evaluátoru, aby sundal celý program. Ne, z funkce nemůžeš "vrátit" bottom....

Jinak Undefined... ptal jsem se tě, zda souhlasíš s tou větou ohledně korektnosti a ... nedříve type error, jiná odpověď teď bottom.....

Nechápu, co se snažíš říct? Že má ten program chytající výjimky špatný design? To je přece jasné, že ano, to všichni víme. Nicméně z formálního hlediska je korektní. Dává ve strict variantě výsledky, které jsou správné a deterministcké. Jak dlouho to ještě chceš řešit?

Pořád tady píšeš o nějakém padání programu, ale to je úplně mimo. Bottom v Haskellu ve smyslu výjimky není žádný pád programu. Dovol, abych si vypůjčil jednu větu odsud: https://www.reddit.com/r/haskell/comments/7wblve/exceptions_in_pure_functions/dtzeu8y/
Bottom is not a real value. It is not even a special expression which crashes the program when evaluated. Instead, it is a mathematical value we use to talk about expressions which diverge or throw exceptions, such as length [0..], undefined, error myErrorMessage, and throw myException.

Vyhození výjimky a její chytání je jasně specifikovaná funkcionalita, žádný pád programu. Má to definované chování. Nejenom v Haskellu se řeší dělení nulou často jako výjimka. Nikdo se nad tím nepozastavuje a nepřemýšlí, jestli tu výjimku může nebo nemůže chytit. Protože může a je to relevatní a definované řešení problému.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 02. 09. 2018, 10:18:14
Diskuze spočívá v tom, že obě strany diskuze předkládají nějaká tvrzení a druhá strana na ně reaguje, a případně vysvětluje, že s nimi souhlasí/nesouhlasí, případně proč. Ne, že jedna strana opakuje nějaké tvrzení - a je jedno jestli nakonec pravdivé nebo nepravdivé, a na tom prostě "trvá". To je pozice židle, ta taky prostě stojí na místě. Diskuze s židlí nemá smysl.

Haskell je matematický zápis. Například následující v R:
Kód: [Vybrat]
sqrt(-3)je nekorektní. Je to stejně nekorektní, jako třeba:
Kód: [Vybrat]
sqrt("hello world")Proč? Protože funkce druhá odmocnina má definiční obor (v R) "x v R, x >= 0". To znamená, že když napíšeš něco z toho výše, tak je to prostě nesmysl. A je úplně jedno, jestli ten program se následně chová deterministicky nebo ne. Je prostě blbě. Formálně blbě a věcně blbě.

Mně totiž připadá, jako kdybys pocházel z oblasti "programování CPU". Assembler totiž nic nevyjadřuje, kromě popisu toho, co to CPU má udělat. Takže jediné, co tě zajímá, je jestli je ten výsledný kód nějakým způsobem podle specifikace deterministický. Jenže od dob assembleru jsme jaksi upgradovali (už dávno...) a teď například překladači sdělíš nějakou specifikaci a tu specifikaci po té implementuješ. Nesoulad tebou dodané specifikace s implementací je vadný program. A je úplně jedno, jestli se ten program následně chová deterministicky.

A tedy k diskuzi - položil jsem několik otázek, několikrát ti vysvětlil, proč je ten kód nekorektní. No reaction. Takhle se chová židle. Takže ti to tady shrnu a pokud se nebudeš namáhat na to nějakým způsobem reagovat, pak je myslím zřejmé, že normálně trolíš a nebo na to prostě nemáš.

Souhlasíš s tímto tvrzením? Obor hodnot odpovědi je: ANO a NE.
Citace
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.

Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.

Tvůj pojem "korektnosti" naprosto ignoruje, že specifikace jazyka říká, že něco není korektní. Například v Haskellu musí sedět typy parametrů při volání funkcí. Následujcí program lze zkompilovat s parametrem GHC "-fdefer-type-check". Ten program normálně běží, zcela deterministicky. Naprosto neodpovídá typovým pravidlům haskellu. Je to podle tebe korektní nebo nekorektní program? Obor hodnot odpovědi: ANO/NE, pokud ANO, tak by mě zajímalo proč.
Kód: [Vybrat]
import Control.Exception (catch, TypeError(..), evaluate, try)

message :: String
message = "hello" ++ (1 :: Int)
main = do
  res <- try (evaluate $ message `seq` message)
  case res of
      Left (TypeError msg) -> putStrLn "Presne tohle uzivatel ocekaval."
      Right s -> putStrLn s

Jinak mám z diskuze s tebou pocit, jako mají asi fyzici vysvětlující kvantovou fyziku. Jak jako že může být jedna částice na víc místech...? Částice je vždycky někde, má konkrétní váhu a rychlost a dá se to změřit.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 02. 09. 2018, 10:21:04
A asi bych si měl udělat účet, abych se moh zpětně opravovat:
Citace
....Naprosto neodpovídá typovým pravidlům haskellu. Je to podle tebe korektní nebo nekorektní program? Obor hodnot odpovědi: ANO/NE...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 02. 09. 2018, 10:49:58
Je v něm typová chyba: vrací se bottom tam, kde se očekává typ, který bottom neobsahuje. Haskell tento typ chyby není schopen odhalit při překladu, slítne to v runtimu.
Neslítne to. Haskell language report někde říká, že když se vrátí bottom, je to nedefinované chování? Neříká. Vyhodí to ArithException, která se dá chytit. Haskell to umožňuje a je to definované chování. Já chápu, že se ti nelíbí, jak je to udělané a že tu výjimku chytám. Mně se to taky nelíbí, dělám to z toho důvodu, protože jsi tvrdil, že v Haskellu nemůže existovat program, který závisí na strict vyhodnocení. Může.

Úplně stejný argument je, že když dereferencuju NULL pointer v C, tak ten SIGSEGV můžu taky odchytit, tudíž je to v pořádku. Jsi trotl, nebo to myslíš vážně?

De facto jsi napsal program, který jde popsat takto "jsi-li ve strictu, vrať toto, jinak spadni/vypiš toto", pointou ale je, že ti minimálně nesedí typy... :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 02. 09. 2018, 10:56:19
De facto jsi napsal program, který jde popsat takto "jsi-li ve strictu, vrať toto, jinak spadni/vypiš toto", pointou ale je, že ti minimálně nesedí typy... :)
Opačně  ;) Jsi-li ve strictu, spadni/vypiš toto, jinak vrať toto...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 02. 09. 2018, 12:21:10
De facto jsi napsal program, který jde popsat takto "jsi-li ve strictu, vrať toto, jinak spadni/vypiš toto", pointou ale je, že ti minimálně nesedí typy... :)
Opačně  ;) Jsi-li ve strictu, spadni/vypiš toto, jinak vrať toto...

Ten spánek se občas asi hodí... :D Ne, máš pravdu, ale pointa je snad jasná. :)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 02. 09. 2018, 12:37:38
Kód: [Vybrat]
sqrt(-3)je nekorektní. Je to stejně nekorektní, jako třeba:
Kód: [Vybrat]
sqrt("hello world")Proč? Protože funkce druhá odmocnina má definiční obor (v R) "x v R, x >= 0". To znamená, že když napíšeš něco z toho výše, tak je to prostě nesmysl
To poukazuje na důležitost typů (well-typed programs), klidně bych taky mohl mít sqrt nad C, kde to bude dobře.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Bacsa 02. 09. 2018, 12:39:30
Jinak mám z diskuze s tebou pocit, jako mají asi fyzici vysvětlující kvantovou fyziku. Jak jako že může být jedna částice na víc místech...?
Takové analogie si může dovolit používat fyzik, takhle jen matou a ruší diskusi.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 03:09:02
Úplně stejný argument je, že když dereferencuju NULL pointer v C, tak ten SIGSEGV můžu taky odchytit, tudíž je to v pořádku. Jsi trotl, nebo to myslíš vážně?
Už jsem ti to psal asi 100x. Dereference NULL pointeru je UNDEFINED BEHAVIOR. NULL pointer NEMŮŽEŠ derefenrencovat, protože nemáš zaručeno vůbec nic, může se stát cokoliv. Výjimku v Haskellu chytat můžeš, protože máš zaručeno, co se stane, je to definované. Jsi opravdu tak hloupý, nebo jenom nechceš takovou základní věc pochopit?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 04:19:22
Haskell je matematický zápis. Například následující v R:
Kód: [Vybrat]
sqrt(-3)je nekorektní. Je to stejně nekorektní, jako třeba:
Kód: [Vybrat]
sqrt("hello world")Proč? Protože funkce druhá odmocnina má definiční obor (v R) "x v R, x >= 0". To znamená, že když napíšeš něco z toho výše, tak je to prostě nesmysl. A je úplně jedno, jestli ten program se následně chová deterministicky nebo ne. Je prostě blbě. Formálně blbě a věcně blbě.
To je právě tvůj problém, že tyhle dvě rozdílné věci nerozlišuješ. sqrt je stejně jako div funkce definovaná pro nějaká čísla. Pro čísla to (většinou) funguje. Pro stringy to nefunguje nikdy. Správně bys měl pro div zadefinovat typ, kde druhý argument by mohlo být jakékoliv číslo kromě 0. Jenže to tak není udělané. Funkce div vyhazuje výjimku, když je dělitel 0. Takže sqrt(-3) typ sedí, protože nemáme typ kladná čísla, máme jen typ reálná čísla. Stejně tak div(1, 0) typ sedí, protože nemáme typ integer čísla mimo 0. Žádná typová chyba tam není. Bylo by hezké, kdyby byly typy definované přesně pro definiční obory všech funkcí, ale nejsou. Proto div vyhazuje výjimku.

Souhlasíš s tímto tvrzením? Obor hodnot odpovědi je: ANO a NE.
Citace
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.
Nesmyslnýma otázkama se odmítám zabývat. Jinak odpověď je ne.

Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.
Úplně nevím, který parametr konkrétně myslíš, ale to je jedno. Všechno typově sedí. Kdyby nesedělo, vůbec se to nepřeloží.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 06:18:00
Úplně stejný argument je, že když dereferencuju NULL pointer v C, tak ten SIGSEGV můžu taky odchytit, tudíž je to v pořádku. Jsi trotl, nebo to myslíš vážně?
Už jsem ti to psal asi 100x. Dereference NULL pointeru je UNDEFINED BEHAVIOR. NULL pointer NEMŮŽEŠ derefenrencovat, protože nemáš zaručeno vůbec nic, může se stát cokoliv. Výjimku v Haskellu chytat můžeš, protože máš zaručeno, co se stane, je to definované. Jsi opravdu tak hloupý, nebo jenom nechceš takovou základní věc pochopit?

Kdyby sis přečetl aspoň jednou to, co ti tu celou dobu píšeme, tak bys věděl, v čem se pleteš.

Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.
Úplně nevím, který parametr konkrétně myslíš, ale to je jedno. Všechno typově sedí. Kdyby nesedělo, vůbec se to nepřeloží.

Opravdu? Četl jsi to tu?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 09:57:57
Úplně stejný argument je, že když dereferencuju NULL pointer v C, tak ten SIGSEGV můžu taky odchytit, tudíž je to v pořádku. Jsi trotl, nebo to myslíš vážně?
Už jsem ti to psal asi 100x. Dereference NULL pointeru je UNDEFINED BEHAVIOR. NULL pointer NEMŮŽEŠ derefenrencovat, protože nemáš zaručeno vůbec nic, může se stát cokoliv. Výjimku v Haskellu chytat můžeš, protože máš zaručeno, co se stane, je to definované. Jsi opravdu tak hloupý, nebo jenom nechceš takovou základní věc pochopit?

Kdyby sis přečetl aspoň jednou to, co ti tu celou dobu píšeme, tak bys věděl, v čem se pleteš.
Hele srovnávat dereferenci NULL pointeru, o čemž standard jasně říká, že je to undefined behavior, s vyhazováním a chytáním výjimky, což ja jasně definovné, to je od tebe fail jako prase. Můžeš se to snažit okecat jak chceš, ale jasně to ukazuje na fakt, že vůbec nevíš, o čem mluvíš.

Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.
Úplně nevím, který parametr konkrétně myslíš, ale to je jedno. Všechno typově sedí. Kdyby nesedělo, vůbec se to nepřeloží.

Opravdu? Četl jsi to tu?
Ty nečteš, co ti píšu já.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 10:11:34
Úplně stejný argument je, že když dereferencuju NULL pointer v C, tak ten SIGSEGV můžu taky odchytit, tudíž je to v pořádku. Jsi trotl, nebo to myslíš vážně?
Už jsem ti to psal asi 100x. Dereference NULL pointeru je UNDEFINED BEHAVIOR. NULL pointer NEMŮŽEŠ derefenrencovat, protože nemáš zaručeno vůbec nic, může se stát cokoliv. Výjimku v Haskellu chytat můžeš, protože máš zaručeno, co se stane, je to definované. Jsi opravdu tak hloupý, nebo jenom nechceš takovou základní věc pochopit?

Kdyby sis přečetl aspoň jednou to, co ti tu celou dobu píšeme, tak bys věděl, v čem se pleteš.
Hele srovnávat dereferenci NULL pointeru, o čemž standard jasně říká, že je to undefined behavior, s vyhazováním a chytáním výjimky, což ja jasně definovné, to je od tebe fail jako prase. Můžeš se to snažit okecat jak chceš, ale jasně to ukazuje na fakt, že vůbec nevíš, o čem mluvíš.

Tak si to tu přečti znovu. Bottom a tak, ostatní ti to tu psali hezky... ale asi je to fakt marný...

Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.
Úplně nevím, který parametr konkrétně myslíš, ale to je jedno. Všechno typově sedí. Kdyby nesedělo, vůbec se to nepřeloží.

Opravdu? Četl jsi to tu?
Ty nečteš, co ti píšu já.

Nesedí ti typy.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 10:27:15
Tak si to tu přečti znovu. Bottom a tak, ostatní ti to tu psali hezky... ale asi je to fakt marný...
Bottom je hrozně široký pojem. Může to být nikdy nekončící výpočet, nebo taky výjimka. Výjimka v Haskellu má jasně definované chování.

Nesedí ti typy.
Hele ráno jsem si zkoušel kloubouk a neseděl mi. Překladač mi říkal, že typy jsou v pohodě a já mu věřím.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 10:27:51
Ono je to stejně zajímavé, jak rozdílně může fungovat komunita. Snažím se tady upozornit, že domýšlet důsledky strict/lazy vyhodnocení v Haskellu není jednoduché a že strict <-> lazy transformace v Haskellu může změnit chování programu až tak, že bude dávat jiný výstup. Haskell komunita na to má jiný názor, prý strict -> lazy transformace změnit výstup nemůže. Tak jim člověk dá důkaz, když si ho nejsou schopni vymyslet sami (ano Haskell asi fakt není pro každého...). Následně se začnou vztekat, co jsem si to jako dovolil! Použil jsem výjimky, jak jsem mohl! No použil, mohl, Haskell to umožňuje...

Soudruzi, takhle nové zákazníky nezískáte. Máte to naprosto špatně marketingově zvládnuté. Můžu vám garantovat, že každý, kdo si tohle vlákno přečte, nebude chtít mít s Haskellem nic společného. A já ho naprosto chápu.

Propagace jazyka se dělá úplně jinak, základem je být vstřícný k začátečníkům a mít co nejvíc příkladů a best practices včetně vyčerpávající dokumentace. Haskell nemá ani jedno. Můžu srovnávat s Rustem a je to prostě úplně jinde než Haskell. Má Haskell něco podobně dobrého a podrobného jak Rust Book (https://doc.rust-lang.org/book/)?. Přístup Rust komunity je taky. Takhle si každý myslí, že ti Haskellisté jsou banda akademických nerdů, kteří si bastlí ten svůj akademický jazyk a vůbec se nevěnují potřebám a problémům bežných uživatelů.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 10:38:15
Ten tvůj "důkaz" je úplně na stejné úrovni jako

Citace
a = b                                | *a
a^2 = ab                          | + a^2 - 2ab
2a^2 - 2ab = a^2 - ab
2(a^2 - ab) = a^2 - ab    | : (a^2 - ab)
2 = 1

Pokud ti to přijde ok, o něčem to vypovídá.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 11:06:12
Ten tvůj "důkaz" je úplně na stejné úrovni jako
Ne není. A tahle věta co jsem napsal, má stejnou vypovídající hodnotu (nulovou), jak tvůj předešlý příspěvěk. Vy jste fakt banda akademických nerdů, kterým nechochází úplně základní praktické věci.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 11:09:39
Možná kdyby sis přečetl, co jsme ti tu psali... Nenapadlo tě, že to možná nedochází tobě...?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 11:38:09
Možná kdyby sis přečetl, co jsme ti tu psali... Nenapadlo tě, že to možná nedochází tobě...?
Možná kdyby sis přečetl, co jsem ti tu psal? Už je ti jasný rozdíl mezi dereferencováním NULL pointeru a chytáním výjimky? Nenapadlo tě, že to možná nedochází tobě?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 11:47:31
Možná kdyby sis přečetl, co jsme ti tu psali... Nenapadlo tě, že to možná nedochází tobě...?
Možná kdyby sis přečetl, co jsem ti tu psal? Už je ti jasný rozdíl mezi dereferencováním NULL pointeru a chytáním výjimky? Nenapadlo tě, že to možná nedochází tobě?

A "rozdíl" mezi undefined behavior a bottom ti je taky jasný? Typy taky sedí? Nebo ty blbosti natáhneš i na 19. stránku?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 11:53:29
A "rozdíl" mezi undefined behavior a bottom ti je taky jasný? Typy taky sedí? Nebo ty blbosti natáhneš i na 19. stránku?
Mně ten rozdíl jasný je, tobě ne. Výjimka v Haskellu NENÍ undefined behavior. Nerozumím tomu, proč tak jasnou věc nejsi schopen pochopit? Není to přece žádná složitá věda?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 16:25:53
Haskell je matematický zápis. Například následující v R:
Kód: [Vybrat]
sqrt(-3)je nekorektní. Je to stejně nekorektní, jako třeba:
Kód: [Vybrat]
sqrt("hello world")Proč? Protože funkce druhá odmocnina má definiční obor (v R) "x v R, x >= 0". To znamená, že když napíšeš něco z toho výše, tak je to prostě nesmysl. A je úplně jedno, jestli ten program se následně chová deterministicky nebo ne. Je prostě blbě. Formálně blbě a věcně blbě.
To je právě tvůj problém, že tyhle dvě rozdílné věci nerozlišuješ. sqrt je stejně jako div funkce definovaná pro nějaká čísla. Pro čísla to (většinou) funguje. Pro stringy to nefunguje nikdy. Správně bys měl pro div zadefinovat typ, kde druhý argument by mohlo být jakékoliv číslo kromě 0.
Přesně!
Citace
Jenže to tak není udělané. Funkce div vyhazuje výjimku, když je dělitel 0. Takže sqrt(-3) typ sedí, protože nemáme typ kladná čísla, máme jen typ reálná čísla.
Nebo jinými slovy: typový systém, který se snaží zabránit nekoretkním programů, propustí nekorektní program. Protože to je obecně nerozhodnutelný problém...
Citace
Stejně tak div(1, 0) typ sedí, protože nemáme typ integer čísla mimo 0. Žádná typová chyba tam není. Bylo by hezké, kdyby byly typy definované přesně pro definiční obory všech funkcí, ale nejsou. Proto div vyhazuje výjimku.
Hele, napadlo tě, že typový systém může propustit nekorektní program? Nebo naopak zabránit korektnímu programu, aby prošel?

Citace
Souhlasíš s tímto tvrzením? Obor hodnot odpovědi je: ANO a NE.
Citace
Pokud jazyk obsahuje deterministické a plně specifikované rutiny pro handling nekorektních stavů programů a neobsahuje konstrukce s nedefinovaným chováním, pak v něm nelze napsat nekorektní program.
Nesmyslnýma otázkama se odmítám zabývat. Jinak odpověď je ne.
Ne, ty se nehodláš zabývat otázkama, které by jaksi ukázaly tvou nekonzistenci. Prostě na to nemáš.

Jinak pokud bych do té věty teda dodal, že ten program splňuje požadavky zákazníka, tak by odpověď byla ano?

Citace
Vysvětlení, proč je kód nekorektní: Ve specifikaci funkce catch a po typové inferenci vychází, že jako první parametr očekává hodnotu typu "IO ()". To je specifikace. Implementace této specifikaci neodpovídá. Souhlas? Obor odpovědi: ANO/NE, pokud ne, tak prosím vysvětlení proč.
Úplně nevím, který parametr konkrétně myslíš, ale to je jedno. Všechno typově sedí. Kdyby nesedělo, vůbec se to nepřeloží.
To není pravda, stačí dát "-fdefer-type-check" a přeloží... je ten přeložený program, který má blbě typy korektní nebo ne? Ty si fakt myslíš, že fakt, že to projde překladačem, říká něco o korektnosti programu?? Kde jsi na takovou blbost přišel?

Citace
Mně ten rozdíl jasný je, tobě ne. Výjimka v Haskellu NENÍ undefined behavior. Nerozumím tomu, proč tak jasnou věc nejsi schopen pochopit? Není to přece žádná složitá věda?
Protože v haskellu není behaviour.... v haskellu jsou pouze výrazy, které nemají behaviour.... ale to je židle, budeš opakovat furt to samý....
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 16:41:13
A jinak teď konkrétně, proč je to blbě: Typový systém je (mimo jiné) od toho, aby dokázal zabránit některým nežádoucím stavům programu. Vzhledem k tomu, že to je obecně nerozhodnutelný problém, tak ve výsledku některé korektní programy nepropustí, nebo naopak některé nekorektní programy projdou. Třeba v Liquid haskellu bys možná u toho sqrt mohl vynutit, aby to bylo pouze pro pozitivní čísla (nejsem si úplně jistý, jestli umí s floatama, ale pro celá čísla by to měl umět). Jaký je teda rozdíl mezi "sqrt(-3)", který kompiler odmítne, protože už předem zjistí, že to není definovaná hodnota - a "sqrt(-3)", které spadne až za běhu, protože to kompilerem prošlo? Jak je možné, že to první je "nekorektní program", to druhé "korektní program", přitom se to akorát liší schopnostma překladače?

Jazyky, které mají totality checking by přesně tenhle program vyhodily jako nekorektní. Protože jsou schopny v typovém systému postihnout "non-termination". Haskell to neumí, takže ten program projde typovým systémem a selže až při běhu. Úplně stejně, jako ti projde typová chyba, když tomu dáš "-fdefer-type-check". Non-termination je bug. Undefined behaviour to není, protože haskellové programy nemají "behaviour". Behaviour má akorát tak ten "IO engine", který ty IO akce spouští.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 17:10:11
Hele to je strašně dlouhé a teoretizuješ o ničem. Kdyby Haskell uměl zajistit, že argumenty funkcí budou jen v definičním oboru funkcí, třeba typovým systémem, možná bychom se mohli bavit o tom, co jsi napsal. Jenomže Haskell to zajistit NEUMÍ. To znamená, že nemáš žádné záruky.

Použil jsem knihovní funkci div, která ti žádné typové záruky nedává. Dělení nulou řeší jako výjimku. To je celé. Souhlasím, že design toho programu není dobrý. Ale to nebylo cílem. Cílem bylo ukázat, že program v Haskellu může záviset na strict vyhodnocení, což platí. Bez ohledu na nějaké hypotetické typové záruky, které v Haskellu nemáš.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 17:25:01
A napíšu to ještě jinak. Podle tebe je v korektní program Haskellu jen takový, kde máš vše dokonale ošetřeno typovým systémem. Musel bys tam mít typy pro datumy, integer čísla včetně nekonečna (výsledek dělení) apod... Jenomže to neplatí. Haskell umožňuje napsat korektní program i bez toho. Nemusíš mít vše řešeno definicí typů, i když je to tak třeba někdy lepší.

On je to totiž dost teoretický koncept. Chápu, jaké to dává záruky, ale taky to něco stojí. Vem si třeba to hloupé integer dělení, jako výsledek musíš definovat typ integer a k tomu plus mínus nekonečno. Teoreticky je to hezký koncept, ale prakticky to moc nikdo nechce, proto taky knihovní funkce div nic takového nemá.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 17:41:17
A napíšu to ještě jinak. Podle tebe je v korektní program Haskellu jen takový, kde máš vše dokonale ošetřeno typovým systémem
Korektní funkcionální program je takový, kde se požadované výrazy v průběhu běhu programu vyhodnotí na hodnotu (+splňuje požadavky zadání). Žádné "chování" neexistuje.
Korektní imperativní program je takový, který má definované chování. (+splňuje požadavky zadání) Žádné "hodnoty" neexistují.

Haskell je funkcionální jazyk....

Citace
Kdyby Haskell uměl zajistit, že argumenty funkcí budou jen v definičním oboru funkcí, třeba typovým systémem, možná bychom se mohli bavit o tom, co jsi napsal. Jenomže Haskell to zajistit NEUMÍ. To znamená, že nemáš žádné záruky
To je obecně vlastnost typových systémů, že zpravidla nejsou dostatečně dokonalé, aby nepropustily nekorektní program...už jsem to tady 3x opakoval...

Citace
Použil jsem knihovní funkci div, která ti žádné typové záruky nedává. Dělení nulou řeší jako výjimku. To je celé. Souhlasím, že design toho programu není dobrý. Ale to nebylo cílem. Cílem bylo ukázat, že program v Haskellu může záviset na strict vyhodnocení, což platí. Bez ohledu na nějaké hypotetické typové záruky, které v Haskellu nemáš.
No, zatím jsi ukázal, že při přechodu Lazy->Strict se může z vyhodnocování některých výrazů stát bottom, a že IO engine haskellu je schopen zachytit nekorektní stav vyhodnocování. Hmmm....

Jinak zpětně myslím, že ten příklad s přístupem na adresu 0 docela sedí. Prostě máš IO engine (>>=), který tak různě volá ty haskellové výrazy a provádí IO podle toho, na co se to vyhodnotí. No a tam se dá (přes catch) nastavit, že když to při tom vyhodnocování kixne, tak se něco zavolá. Podobná situace, jako když OS předává řízení programu, a když dojde k nějakému nekorektnímu stavu (přístup na adresu 0), tak je schopen zavolat signal handler SIGSEGV, který si před tím program nainstaloval.

Jinak díky, že jsi opět neodpověděl ani najeden dotaz, který jsem předtím položil. Prostě na to nemáš.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 17:51:42
Podívej, tohle nemá cenu. Klidně si mysli, že korektní programy můžou být jen takové, kde je vše dokonale podchyceno typovým systémem. Pokud je tohle podle tebe definice korektního programu, tak prakticky žádné neexistují. Ale mně je to už celkem jedno. Odmítám diskutovat s akademikem, kterému něco řekli ve škole a on ty poučky naprosto chybně aplikuje v reálných případech.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 03. 09. 2018, 17:59:58
Zatím jsi to ty, kdo tu aplikuje chybně prakticky všechno... :) Jinak gratuluji k 19. stránce.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 18:03:10
Zatím jsi to ty, kdo tu aplikuje chybně prakticky všechno... :) Jinak gratuluji k 19. stránce.
Už ti došlo, jaký je rozdíl mezi undefined behavior a chytání výjimky?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 18:46:40
Podívej, tohle nemá cenu. Klidně si mysli, že korektní programy můžou být jen takové, kde je vše dokonale podchyceno typovým systémem.
Zvláštní, asi 4x už jsem tu napsal, že si tohle nemyslím...
Citace
Pokud je tohle podle tebe definice korektního programu, tak prakticky žádné neexistují.
Není.... napsal jsem ti, co považuji za korektní program a tohle to fakt není :) Tak co si ještě podle tebe myslím? Zabili Kennyho?

Citace
Ale mně je to už celkem jedno. Odmítám diskutovat s akademikem, kterému něco řekli ve škole a on ty poučky naprosto chybně aplikuje v reálných případech.
Ale ty nediskutuješ :) Položil jsem ti pár jednoduchých otázek a ty ses absolutně nenamáhal odpovědět.... S židlí se diskutovat nedá, židle jen trvá na svém... a pro takové fakt haskell není...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 18:51:24
Zatím jsi to ty, kdo tu aplikuje chybně prakticky všechno... :) Jinak gratuluji k 19. stránce.
Už ti došlo, jaký je rozdíl mezi undefined behavior a chytání výjimky?
No, a už jsi pochopil, že haskellový program nemá žádné "behaviour"? Protože je jako jeden z hodně mála jazyků opravdu čisté funkcionální?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 21:22:10
Zatím jsi to ty, kdo tu aplikuje chybně prakticky všechno... :) Jinak gratuluji k 19. stránce.
Už ti došlo, jaký je rozdíl mezi undefined behavior a chytání výjimky?
No, a už jsi pochopil, že haskellový program nemá žádné "behaviour"? Protože je jako jeden z hodně mála jazyků opravdu čisté funkcionální?

Víš, tvůj probém je, že máš naučené teoretické poučky, které ale úplně špatně aplikuješ v praxi. Haskellovský program samozřejmě má "behavior", kdyby neměl, nikdo by nechtěl Haskellovské programy používat. Od programu se tak nějak z principu očekává, že bude něco dělat. Takové polopravdy a nesmysly uvádíš pořád.

I v Haskellu narazíš na undefined behavior: http://hackage.haskell.org/package/base-4.11.1.0/docs/Foreign-StablePtr.html
If the argument to deRefStablePtr has already been freed using freeStablePtr, the behaviour of deRefStablePtr is undefined.

Proto diskuze s tebou nemá smysl, žiješ svázaný teoriemi bez vazby na praxi.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 21:46:08
Víš, tvůj probém je, že máš naučené teoretické poučky, které ale úplně špatně aplikuješ v praxi. Haskellovský program samozřejmě má "behavior", kdyby neměl, nikdo by nechtěl Haskellovské programy používat. Od programu se tak nějak z principu očekává, že bude něco dělat. Takové polopravdy a nesmysly uvádíš pořád.
No vidíš, a od Haskellových programů se to neočekává. Víš jaký je výsledek vyhodnocení funkce main? IO (). To nic nedělá, to je prostě hodnota.

Když bychom haskellové programy omezili, že by nereagovaly na vstup, tak bychom nepotřebovali Monad, stačil by List. Takže by Haskellový program mohl vypadat třeba takhle:
Kód: [Vybrat]
data IO = UmazVejce Int | DejObsahPanveNaTalir | PostavTalirNaStul | NedelejNic
main :: [IO]
main = [ UsmazVejce (2 + 3), DejObsahPanveNaTalir, PostavTalirNaStul ]
Vidíš nějaké chování? Já ne, tohle je prostě seznam toho, co se má udělat. Ta monadická struktura je v podstatě totéž, akorát umožňuje zapsat reakce na vstupy.

Citace
I v Haskellu narazíš na undefined behavior: http://hackage.haskell.org/package/base-4.11.1.0/docs/Foreign-StablePtr.html
If the argument to deRefStablePtr has already been freed using freeStablePtr, the behaviour of deRefStablePtr is undefined.
Jojo, to je behaviour IO akce, nikoliv haskellového programu...

Citace
Proto diskuze s tebou nemá smysl, žiješ svázaný teoriemi bez vazby na praxi.
Jojo, mě se vždycky líbí, jak ti, kteří odmítnout odpovědět na jednoduché otázky, a začnou volat něco ve stylu "demagogie" a "akademický teoretik", "svázený teoriemi" a podobně. Přitom je strašně jednoduché ukázat, že jsem demagog nebo akademický teoretik: odpovědět. Ale to židle nezvládne. Židle trvá na svém. Mimochodem, já si udělám sbírku těchhle fází, znáš ještě nějaké? Ale ztrapňuješ se sám. Stačí odpovědět.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 22:01:28
Aha, takže IO akce v Haskelovském programu není součástí Haskellovského programu... Co tam máš dál za perly, jaké další nesmyslné definice mimo realitu jsi ještě schopen vymyslet?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 03. 09. 2018, 23:03:59
Aha, takže IO akce v Haskelovském programu není součástí Haskellovského programu... Co tam máš dál za perly, jaké další nesmyslné definice mimo realitu jsi ještě schopen vymyslet?
Konkrétní chování IO akce není součástí Haskell jazyka. Je to součástí nějakých knihoven. Haskellový program (ve smyslu toho, co je napsáno ve zdrojáku, nikoliv výsledné binárky) vyprodukuje, co se asi tak má s těmi voláními provést - a to se pak provede.  Nebo snad někde v tom svém zdrojáku vidíš nějaké příkazy? Já tam vidím akorát monadické řetězení - což je jenom trošičku složitější stavění Listu.

U main funkce máš přímo napsaný typ: IO (). To je hodnota. Zkus to, jaké má "hodnota" chování? Třeba ten zdroják, kde bychom to zjednodušili:
Kód: [Vybrat]
main = take 1 [ UdelejPalacinku, UdelejPalacinku, UdelejPalacinku ]Jaké bude mít ten program chování? Žádné? Teprve když to něco začne vykonávat, tak se podívá do knihovny, najde co má udělat "UdelejPalacinku" a to provede? A k tomu undefined - tohle:
Kód: [Vybrat]
main = [UdelejPalacinku] ++ [**tohle je necitelne**..undefined] ++[PostavTalirNaStul]Když dostaneš takovýhle seznam úkolů, tak ho sice deterministicky můžeš vykonat (nečitelné věci prostě neuděláš), ale ten seznam prostě není korektní, protože tam nečitelné věci nemají co dělat. Už jen proto, že třeba nelze odpovědět na otázku "a bylo vše na seznamu vykonáno".

Je to trošičku jiné paradigma... Trošičku je to v tom stylu, jako bys měl generátor programů, které se teprve následně spouští. Ten generátor sám o sobě nic udělat neumí. Je zcela pure.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 03. 09. 2018, 23:38:56
Ale tohle všichni vědí, to je přece jasné. Pointa je, že to uživatele vůbec nezajímá. On chce, aby program něco dělal, pro něj musí mít chování. Takže sice můžeš říct, že "polovina Haskell programu" jenom vyprodukuje, co se má udělat, ale reálně k tomu potřebuješ i tu "druhou polovinu", která to opravdu vykoná. Ty uvažuješ jenom o té první půlce, jenomže ta ti je bez té druhé úplně k ničemu. Taková hezká akademická úvaha, co se nám nehodí, to odsuneme jinam a nebudeme se tím zabývat. Reálně to v tom programu ale je. Musí být. Bez toho by nefungoval.

Úplně stejná analogie je s undefined behavior ve StablePtr. Uživatele vůbec nezajímá, že je to IO monáda a že to podle tebe nepatří do Haskell programu. Uživatele ale sakra bude zajímat, když to použiješ blbě a program mu spadne. Můžeš mu zkusit vysvětlit, že vlastně nespadl Haskell program, ale něco úplně jiného, co ty už neřešíš. Obávám se ale, že tě požene svinským krokem.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 00:37:41
Ale tohle všichni vědí, to je přece jasné. Pointa je, že to uživatele vůbec nezajímá. On chce, aby program něco dělal, pro něj musí mít chování. Takže sice můžeš říct, že "polovina Haskell programu" jenom vyprodukuje, co se má udělat, ale reálně k tomu potřebuješ i tu "druhou polovinu", která to opravdu vykoná. Ty uvažuješ jenom o té první půlce, jenomže ta ti je bez té druhé úplně k ničemu. Taková hezká akademická úvaha, co se nám nehodí, to odsuneme jinam a nebudeme se tím zabývat. Reálně to v tom programu ale je. Musí být. Bez toho by nefungoval.
Ta druhá půlka není tvůj haskellový program. A ta druhá půlka očekává, že vyhodnocení tvého haskellového programu té druhé půlce dá poměrně jasnou specifikaci, co má ta druhá půlka dělat. A specifikace "undefined" je jaksi poněkud nekorektní.

Citace
Úplně stejná analogie je s undefined behavior ve StablePtr. Uživatele vůbec nezajímá, že je to IO monáda a že to podle tebe nepatří do Haskell programu. Uživatele ale sakra bude zajímat, když to použiješ blbě a program mu spadne. Můžeš mu zkusit vysvětlit, že vlastně nespadl Haskell program, ale něco úplně jiného, co ty už neřešíš. Obávám se ale, že tě požene svinským krokem.
Ale to jsme se přesně dostali do té imperativní části, která je ta jediná, kterou znáš. Jenomže ta pointa je, že ten tvůj program může být nekorektní i navzdory tomu, že z té "druhé poloviny" používáš jenom IO akce s definovaným chováním.

Ten tvůj program vygeneruje specifikaci, kterou pak nějaký "IO interpret" vykonává. Ty klidně můžeš vyměnit "IO" za nějaký tvůj vlastní Monad, vytvořit si nějakou simulaci IO a výsledek si odsimulovat. To se mimochodem používá v unit testech. Jenomže v tvém programu nemůžeš - protože ta specifikace není korektní. IO monad je schopen zachytit "null pointer exception". Jiný interpret monadické struktury toho schopen není. Takže kdybych tvůj kód transformoval do pure unit testu (v podstatě jenom výměnou IO za nějakou typeclassu), tak prostě v XStrict slítne a není vůbec žádná šance to  uchodit.

Ono se dá říct, že ten tvůj program je "implementation dependent". Protože IO je svým způsobem jenom knihovna a to, že je schopna tohle odchytit je na úrovni toho, že zrovna IO umí odchytit SIGSEGV. Magic. Občas se hodí mít možnost SIGSEGV chytit. Ale program, který to háže fakt není korektní.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 04. 09. 2018, 01:00:10
Zase píšeš úplné nesmysly. Ten program není implementation dependent. Je naprosto jasné, kde a jak a kde se ta výjimka dá chytit. Všechno máš specifikované tady: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Exception.html
Už mě to s tebou fakt nebaví. Máš nějakou specifikaci chování výjimek v Haskellu, ale ty ji vůbec neznáš. Proč si to nejdřív nepřečteš, než začneš generovat nějaká rádoby moudra?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 01:19:52
Zase píšeš úplné nesmysly. Ten program není implementation dependent. Je naprosto jasné, kde a jak a kde se ta výjimka dá chytit. Všechno máš specifikované tady: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Exception.html
Už mě to s tebou fakt nebaví. Máš nějakou specifikaci chování výjimek v Haskellu, ale ty ji vůbec neznáš. Proč si to nejdřív nepřečteš, než začneš generovat nějaká rádoby moudra?
Jasně, a teď prosím ukaž, jak budeš chytat undefined v non-IO monadu. Exceptiony normálně chytat jdou a je to pure:

Viz např: http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html (http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html).

Jsem jedno velké ucho...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 04. 09. 2018, 01:28:59
Jasně, a teď prosím ukaž, jak budeš chytat undefined v non-IO monadu. Exceptiony normálně chytat jdou a je to pure:

Viz např: http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html (http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html).

Jsem jedno velké ucho...

Proč bych to jako měl dělat? Vůbec to nepotřebuju. Mně stačí chytit výjimku v IO. Je jasně specifikované, že v IO se výjimky chytat dají. NENÍ to implementation dependent, jak ses snažil nesmyslně tvrdit. Příště si přečti specifikaci, než začneš zase psát hovadiny.

Mimochodem co máš pořád s tím undefined? Já nechytám undefined. Chytám aritmetickou výjimku, to není undefined.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 01:50:32
Jasně, a teď prosím ukaž, jak budeš chytat undefined v non-IO monadu. Exceptiony normálně chytat jdou a je to pure:

Viz např: http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html (http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html).

Jsem jedno velké ucho...

Proč bych to jako měl dělat? Vůbec to nepotřebuju. Mně stačí chytit výjimku v IO.
Nojo... víš, to je tak: pokud v tom programu provedeme výměnu IO za třeba "Either SomeException" obalené nějakým WriterT, kde si odchytíme ty putStrLn, a všechny ty funkce budou na stejné vstupy dávat stejné výstupy, pak by tvůj program měl ve výsledku udělat totéž. To je tak nějak základem pure programování. Takže pokud taková transformace není možná, pak je tvůj program nekorektní. A vzhledem k tomu, že ty tvrdíš, že je korektní, tak bych očekával, že mi ukážeš, jak se to krásně udělá. Nebo zase jenom něco tvrdíš a skutek utek?

Citace
Je jasně specifikované, že v IO se výjimky chytat dají. NENÍ to implementation dependent, jak ses snažil nesmyslně tvrdit. Příště si přečti specifikaci, než začneš zase psát hovadiny.
No jo, ale popis libc není popis chování jazyka C, stejně tak popis knihovních funkcí není popisem Haskellu. A "base" je normální knihovna.....

Citace
Mimochodem co máš pořád s tím undefined? Já nechytám undefined. Chytám aritmetickou výjimku, to není undefined.
Jasně, ukaž jak rozlišíš v pure kódu undefined a aritmetickou výjimku. Třeba můžeš začít s tím MonadCatch, rovnou mi na to napiš unit test. Těším se.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 04. 09. 2018, 10:21:52
Nojo... víš, to je tak: pokud v tom programu provedeme výměnu IO za třeba "Either SomeException"...
Když IO vyměním za australského klokana, tak to taky nebude fungovat. Vypovídá to o něčem? Ne. Nevymýšlej blbosti a drž se specifikace jazyka: https://www.haskell.org/tutorial/io.html
The use of the name main is important: main is defined to be the entry point of a Haskell program (similar to the main function in C), and must have an IO type, usually IO ().

No jo, ale popis libc není popis chování jazyka C, stejně tak popis knihovních funkcí není popisem Haskellu. A "base" je normální knihovna.....
Už ti asi 20 stránek vysvětluju, jak fungují výjimky v Haskellu a pořád jsi to nepochopil a jsi schopen psát takové blbosti, jakože je to implementation dependent. Tak si přečti relevantní specifikace, než se k něčemu začneš vyjadřovat. O člověku, který nezná standardní C knihovnu, se fakt nedá říct, že umí C, i když si třeba pure akademik myslí opak.

Jasně, ukaž jak rozlišíš v pure kódu undefined a aritmetickou výjimku. Třeba můžeš začít s tím MonadCatch, rovnou mi na to napiš unit test. Těším se.
Nic ti ukazovat nebudu, nepotřebuju v pure kódu chytat aritmetickou výjimku. Nebudu dělat každou blbost, kterou si vymyslíš. Výjimku chytám v IO, tak jak se to má dělat a jak je to obvyklé. Hotovo. Tečka.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Dr. Heinz Doofenshmirtz 04. 09. 2018, 15:03:03
Mohli byste mi napsat kdo z vás má pravdu, nechce se mi to číst celé :)
Název: Jak je to s jazyky rychlejšími než C++
Přispěvatel: Miloslav Ponkrác 04. 09. 2018, 16:40:56
Citace
Mohli byste mi napsat kdo z vás má pravdu, nechce se mi to číst celé

To už je takový evergreen, že Java/Haskell/cokoli je rychlejší než C/C++. Zbožné přání milovníků toho kterého jazyka. K tomu většinou také přísluší cinknutý benchmark, který to dokazuje - to je také evergreen.

Na to, aby jazyk X mohl být rychlejší než C/C++, potřebujete mít splněny dvě podmínky:

1) Mít ve zdrojovém kódu programovacího jazyka X více informací pro optimalizaci než má C/C++. Ne že by to byl až takový problém mít takový programovací jazyk vytvořit, ale moderní trend už hodně dlouho je tvořit jazyky přesně opačné.

2) Dát do vývoje optimalizovaného kompilátoru programovacího jazyka X dostatečné prachy. Musíte konkurovat astronomickým částkám, které byly dány do vývoje optimalizovaných C/C++ kompilátorů.

Zejména podmínce ad 2) se hodně blbě konkuruje.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 17:41:15
Já myslím, že je problém v tom, že jsi se neobtěžoval odpovědět na tu otázku ohledně toho, co považuješ za korektnost programu. Ta otázka byla v tom stylu, jestli, za předpokladu, že ten program dává správné výsledky a v jazyce neexistují konstrukce s nedefinovaným chováním, jestli vůbec je možné v takovém jazyce napsat nekorektní program. Vypadá to, že ta odpověď by měla znít "ANO", ale ty jako židle trváš na svém a strašně se bojíš mi na cokoliv takového odpovědět.

Stejně tak otázka byla, jestli ten program s těmi chybnými typy, ale který lze přeložit s defer-type-check je korektní a opět by odpověď měla být ANO. Ale ty se prostě bojíš diskutovat. Člověk by čekal, že si za svým názorem budeš stát, ale ty se bojíš.

Navíc když se podíváš do těch 20 let starých paperů, kde ty výjimky zaváděli, tak ti lidi v té době přesně takhle, jako ty, mysleli. Akorát že od té doby uteklo hodně vody a dneska se ten náhled trošku změnil. S bottom se strašně blbě pracuje, to, co před 20 lety vypadalo jako skvělý nápad se ukázalo jako v zásadě naprosto nepoužitelné. Ona to prostě je chyba programu. No a dneska s různými snahami o formální verifikace a odstranění chybných stavů se od toho totálně upustilo. Naopak se hodně pracuje s různými zaměnami typů, čistě prakticky pak s tím, jak jednoduše vyrábět třeba ty unit-testy na non-pure kód apod. A tohle všechno prostě přestane fungovat, pokud ten program dojde do nekorektního stavu.

Ono to fakt je něco ve stylu null-pointer-exception. Vzhledem k tomu, že na UNIXu je to všechno definované, pak lze tímto způsobem (na UNIXu) vyrobit korektní program. Splňuje všechny tvé požadavky... které se domnívám, že bereš pod pojmem "korektní".

Takže ano, z hlediska operational-semantics to korektní je. Což už říkám asi tak od začátku. Z hlediska smyslu těch rovnic nikoliv. Což taky říkám od začátku. Ano, je to akademické. Ono vůbec Haskell je takový akademický. Není pro lopaty.

Citace
Mimochodem co máš pořád s tím undefined? Já nechytám undefined. Chytám aritmetickou výjimku, to není undefined.
Celý rozdíl mezi undefined a aritmetickou výjimkou je to, že to je jiný typ. Tak asi na té úrovni, že z jednoho vylítně "UserError" a z druhého "ArithException". V pure kódu se to chytnout nedá, v IO se to liší akorát v typu. Já tu větu pochopil, že se to v něčem zásadním liší... a vysvětlil bys mi teda v čem?

Ale víš, tohle je sranda - fakt mě baaaaví, jak píšeš že tomu nerozumím, to je fakt psina... ale teď jsem si prošel svoje zdrojáky, a kromě toho, že v těch starších místo "throwIO . userError" používám přímo "error" (protože holt se člověk učí..), tak asi tak v 95% případů v pure funkcích tam u toho jsou popisky "internal errror, cannot happen", v 5% "nebudu řešit chybu v dekódování toho, co jsem sám zakódoval, slítni" a v 0% ve stylu "signalizuj něco někam, kde se to chytá".

Takže když tady přijdeš s tím, že Haskell je strašný jazyk, jak XStrict může rozbít kód...tak mi to připadá...poněkud úsměvné. Programy, které to rozbije, si to zaslouží, jakýkoliv náznak nějaké formální verifikace by je vyhodil z okna i s tím programátorem.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 17:50:40
Citace
Ta otázka byla v tom stylu, jestli, za předpokladu, že ten program dává správné výsledky a v jazyce neexistují konstrukce s nedefinovaným chováním, jestli vůbec je možné v takovém jazyce napsat nekorektní program. Vypadá to, že ta odpověď by měla znít "ANO", NE ale ty jako židle trváš na svém a strašně se bojíš mi na cokoliv takového odpovědět.
Ještě se to po sobě naučím číst....
 ;)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 20:40:28
Někdy je potřeba se zamyslet....

Proč ten tvůj program není v Strict korektní?

Protože "seq" není pure, pokud je první parametr bottom. Proč "seq" není pure? Protože bottom není observable a seq mění chování v závislosti na tom, jestli to bottom je nebo není. Takže není pure. Používání non-pure funkcí v pure kontextu v haskellu má nedefinované chování (non-pure -> má chování). Lze snadno vyrobit třeba i pomocí unsafePerformIO.

Stačí takhle?
Název: Re:Jak je to s jazyky rychlejšími než C++
Přispěvatel: JSH 04. 09. 2018, 21:18:13
Citace
Mohli byste mi napsat kdo z vás má pravdu, nechce se mi to číst celé

To už je takový evergreen, že Java/Haskell/cokoli je rychlejší než C/C++. Zbožné přání milovníků toho kterého jazyka. K tomu většinou také přísluší cinknutý benchmark, který to dokazuje - to je také evergreen.
Tak příspěvky, že je Haskell rychlejší než c++, by v tomhle flamu napočítal na jedné ruce i nešikovný truhlář. Ten flame je úplně o něčem jiném.
Název: Re:Jak je to s jazyky rychlejšími než C++
Přispěvatel: Miloslav Ponkrác 04. 09. 2018, 21:37:29
Citace
Tak příspěvky, že je Haskell rychlejší než c++, by v tomhle flamu napočítal na jedné ruce i nešikovný truhlář. Ten flame je úplně o něčem jiném.

Jo, připadl jsem si s tou odpovědí jako mimoň, i když reagovala na nadpis tématu.

Pak je tu diskuse dvou lidí o tom, co subjektivně považují dle názoru za korektní a co nikoli. Nicméně Haskell neznám natolik, abych mohl posoudit.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 04. 09. 2018, 21:41:12
Někdy je potřeba se zamyslet....

Proč ten tvůj program není v Strict korektní?

Protože "seq" není pure, pokud je první parametr bottom. Proč "seq" není pure? Protože bottom není observable
Zamyslel ses asi málo. Bottom jako výjimka je v Haskellu observable, dá se chytit. Což je přesně to, co dělám.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: top 04. 09. 2018, 21:53:28
...Což je přesně to, co dělám.
https://www.urbandictionary.com/define.php?term=Bottom (https://www.urbandictionary.com/define.php?term=Bottom)
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: Cikáda 04. 09. 2018, 22:08:11
Což je přesně to, co dělám.

Možná bys to právě dělat neměl :D
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 22:08:36
Někdy je potřeba se zamyslet....

Proč ten tvůj program není v Strict korektní?

Protože "seq" není pure, pokud je první parametr bottom. Proč "seq" není pure? Protože bottom není observable
Zamyslel ses asi málo. Bottom jako výjimka je v Haskellu observable, dá se chytit. Což je přesně to, co dělám.
Bottom není observable v pure kódu. Ty to chytáš v IO. Ale ono je to dokonce ještě jednodušší, funkce seq má signature:
Kód: [Vybrat]
seq :: a -> b -> bTahle funkce má pouze 2 možné implementace (Free theorems):
Kód: [Vybrat]
seq a = id
seq a = bottom
Ten polymorfní typ říká, že ta funkce (seq) o tom prvním parametru vůbec nic neví. No a tady výsledek té funkce evidentně na tom parametru závisí.

Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 04. 09. 2018, 22:19:55
Andy, seq v Haskellu je "magic": https://stackoverflow.com/questions/6442019/how-does-seq-force-functions

seq cannot be implemented in Haskell. Instead, it is a primitive "hook" into evaluation to weak-head normal form in whatever runtime your Haskell is running on. E.g. on GHC it is compiled to a case in GHC Core, which triggers evaluation to the outermost constructor.

Hele, nechceš se na to už vykašlat? Není lepší jít za holkama, dát si pivo, nebo si třeba jít zaběhat? Nejen computer science živ je člověk. Já s dovolením půjdu za těma holkama.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 22:24:14
Andy, seq v Haskellu je "magic": https://stackoverflow.com/questions/6442019/how-does-seq-force-functions

seq cannot be implemented in Haskell. Instead, it is a primitive "hook" into evaluation to weak-head normal form in whatever runtime your Haskell is running on. E.g. on GHC it is compiled to a case in GHC Core, which triggers evaluation to the outermost constructor.

Hele, nechceš se na to už vykašlat? Není lepší jít za holkama, dát si pivo, nebo si třeba jít zaběhat? Nejen computer science živ je člověk. Já s dovolením půjdu za těma holkama.
Ano, přesně. Seq není pure funkce, pokud je první parametr bottom. Souhlas? Pokud ne, proč?
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 04. 09. 2018, 22:46:47
Ad pure funkce: to není o tom jak je ta funkce implementovaná (FFI volání klidně můžou být z hlediska haskellu pure), ale že závisí výhradně na tom, jaké jim přijdou parametry. A funkce "seq" neví o prvním parametru vůbec nic, takže na něm nemůže záviset. Jenomže závisí. Přinejlepším by ta funkce musela schematicky vypadat takhle:
Kód: [Vybrat]
seq a b = if isBottom a then bottom else b
jenomže to nejde. Non-observable znamená, že žádná funkce isBottom neexistuje. Nejde na to udělat pattern match. A ta funkce výše NENÍ identická:
Kód: [Vybrat]
seq :: () -> b -> b
seq a b = case a of () -> b
Protože tady dělám pattern-match na (). A to observable je.

Jinak non-CS věnuju docela hodně času, akorát v jiné denní hodiny ;D
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 05. 09. 2018, 08:50:17
A tady je na to téma článeček od někoho, kdo tomu na rozdíl od mě rozumí http://www.janis-voigtlaender.eu/papers/TheImpactOfSeqOnFreeTheoremsBasedProgramTransformations.pdf (http://www.janis-voigtlaender.eu/papers/TheImpactOfSeqOnFreeTheoremsBasedProgramTransformations.pdf)
Citace
Since seq violates the parametricity property dictated by its type, other terms that are built using seq might do so as well.
Interpretoval bych to tak, že použití seq určitým způsobem může rozbít očekávání, která existují ohledně haskellého programu. Lepší typový systém by mohl být schopen omezit použití seq způsobem, kdy to tato očekávání nerozbije.

No a vzhledem k tomu, že ta výsledná pravidla při existenci seq a bottom jsou poněkud složitější, tak kdo v haskellu programuje, tak se používání "bottom" vyhýbá, protože v takovém modelu je všechno výrazně jednodušší a funguje jak má.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: lopata 05. 09. 2018, 10:06:25
Ano, přesně. Seq není pure funkce, pokud je první parametr bottom. Souhlas? Pokud ne, proč?
Já ti řeknu proč. Zase se snažíš aplikovat teoretické poučky, které jsi slyšel ve škole, ale děláš to úplně blbě.

Tak zaprvé, seq v Haskellu implementovat nejde. Proto nemá smysl o seq uvažovat jako o Haskellovské funkci, ten tvůj formální popis je k ničemu. seq je nějaký "magic", který je zadrátovaný v překladačí, v podstatě je to implementation dependent, GHC to dělá nějak, jiný překladač to může dělat jinak. Použitím seq se dostáváš do vážných problémů: https://stackoverflow.com/questions/12687392/why-is-seq-bad

The seq function is not lambda definable (i.r., cannot be defined in the lambda-calculus), which means that that all the results from lambda calculus can no longer be trusted when we have seq.

Zadruhé, ty řešíš seq, ale to vůbec nemáš dělat, máš řešit bang patterns, protože -XStrict je implementované pomocí bang patterns. Ano, bang patterns můžou interně používat seq, ale to je implementační detail, klidně to může být udělané i úplně jinak. Kdyby sis přečetl specifikaci bang patterns, tak bys narazil na jednu důležitou větu, která rozbíjí všechny tvoje teorie, chování pro bottom je jasně definované: https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/bang-patterns.html

The key change is the addition of a new rule to the semantics of pattern matching in the Haskell 98 report. Add new bullet 10, saying: Matching the pattern !pat against a value v behaves as follows: if v is bottom, the match diverges otherwise, pat is matched against v.

Jak vidíš, strict vyhodnocení v Haskellu není pro normální lidi. Normální člověk nedokáže domyslet důsledky, nepodařilo se to ani tobě. V podstatě by na každé instalačce Haskellu mělo být varování:

"POZOR! NEBEZPEČNÉ! UCHOVÁVEJTE MIMO DOSAH BĚŽNÝCH PROGRAMÁTORŮ. NEPOUŽÍVEJTE STRIKTNĚ. NEOPATRNÉ POUŽITÍ MŮŽE PORUŠIT PRAVIDLA LAMBDA KALKULU. V PŘÍPADĚ POTÍŽÍ VYHLEDEJTE NEJBLIŽŠÍHO TEORETICKÉHO MATEMATIKA."

Tím by se myslím vyřešila spousta problémů.
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: andy 06. 09. 2018, 00:32:29
Citace
Zadruhé, ty řešíš seq, ale to vůbec nemáš dělat, máš řešit bang patterns, protože -XStrict je implementované pomocí bang patterns. Ano, bang patterns můžou interně používat seq, ale to je implementační detail, klidně to může být udělané i úplně jinak
Já bych si nesměle tipnul, že bang patterns a seq jsou isomorfní. Seq jde implementovat pomocí bang pattern, a bang pattern jde implementovat tak, že se předkaždé volání funkce vrazí seq s parametrama.... Takže řeším seq a je to přesně to, o čem je celou dobu řeč. To, jak je to implementované, je fakt implementační detail...

Citace
Jak vidíš, strict vyhodnocení v Haskellu není pro normální lidi. Normální člověk nedokáže domyslet důsledky, nepodařilo se to ani tobě. V podstatě by na každé instalačce Haskellu mělo být varování:

"POZOR! NEBEZPEČNÉ! UCHOVÁVEJTE MIMO DOSAH BĚŽNÝCH PROGRAMÁTORŮ. NEPOUŽÍVEJTE STRIKTNĚ. NEOPATRNÉ POUŽITÍ MŮŽE PORUŠIT PRAVIDLA LAMBDA KALKULU. V PŘÍPADĚ POTÍŽÍ VYHLEDEJTE NEJBLIŽŠÍHO TEORETICKÉHO MATEMATIKA."

Tím by se myslím vyřešila spousta problémů.
Ne, mělo by tam být varování:

Nevyhazujte výjimky v pure kódu (ať už jakýmkoliv způsobem), protože pravidla pro použití speciálně s použitím seq jsou dost složitá a může to porušit free theorems, na kterých je postavena spousta věcí mimo jiné v optimalizátoru a může to vést k nedefinovanému chování. V případě potřeby vyhledejte nejbližšího teoretického matematika.

Hmmm.... Možná bych mohl spočítat, kolikrát něco takového v tomhle threadu padlo... tak 10x? 20x? V tebou odkazovaných textech týkajících se vyhazování výjimek v pure kódu to bylo napsané. Narazil jsem na to v 15 let staré učebnici haskellu, předpokládám, že dneska to budou akcentovat ještě víc...
Název: Re:Rychlost Haskell vs. C++
Přispěvatel: BoneFlute 06. 09. 2018, 16:20:53
Nojo... víš, to je tak: pokud v tom programu provedeme výměnu IO za třeba "Either SomeException" obalené nějakým WriterT, kde si odchytíme ty putStrLn, a všechny ty funkce budou na stejné vstupy dávat stejné výstupy, pak by tvůj program měl ve výsledku udělat totéž. To je tak nějak základem pure programování. Takže pokud taková transformace není možná, pak je tvůj program nekorektní. A vzhledem k tomu, že ty tvrdíš, že je korektní, tak bych očekával, že mi ukážeš, jak se to krásně udělá.

Toto bych zdůraznil.