Rychlost Haskell vs. C++

Radek

Re:Rychlost Haskell vs. C++
« Odpověď #150 kdy: 29. 08. 2018, 20:28:44 »
Citace od: 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é foldl (+) hodneDlouhySeznamCisel?

To vybuchne na stack overflow.


Re:Rychlost Haskell vs. C++
« Odpověď #151 kdy: 29. 08. 2018, 20:52:32 »
Citace od: Radek kdy 29. 08. 2018, 20:28:44
Citace od: 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é 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 :)

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #152 kdy: 29. 08. 2018, 22:15:59 »
Citace od: Cikáda kdy 29. 08. 2018, 19:46:55
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.

Citace od: Cikáda kdy 29. 08. 2018, 19:46:55
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:

{-# 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:

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:

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í:

{-# 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:

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:

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

andy

Re:Rychlost Haskell vs. C++
« Odpověď #153 kdy: 29. 08. 2018, 22:36:14 »
CitaceMá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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #154 kdy: 29. 08. 2018, 22:52:42 »
Citace od: andy kdy 29. 08. 2018, 22:36:14
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í.


v

Re:Rychlost Haskell vs. C++
« Odpověď #155 kdy: 29. 08. 2018, 22:58:57 »
Citace od: Radek kdy 29. 08. 2018, 20:28:44
Citace od: 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é 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?

Re:Rychlost Haskell vs. C++
« Odpověď #156 kdy: 29. 08. 2018, 23:02:06 »
Citace od: lopata kdy 29. 08. 2018, 22:15:59
Citace od: Cikáda kdy 29. 08. 2018, 19:46:55
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 ;)

Citace od: lopata kdy 29. 08. 2018, 22:15:59
Citace od: Cikáda kdy 29. 08. 2018, 19:46:55
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:

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ě?

Citace od: andy kdy 29. 08. 2018, 22:36:14
nevím, jestli jsi měl někde vyčíslitelnost

Z vlákna soudím, že nikoliv.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #157 kdy: 29. 08. 2018, 23:09:06 »
Citace od: lopata kdy 29. 08. 2018, 22:52:42
Citace od: andy kdy 29. 08. 2018, 22:36:14
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.

Citaceale 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.

CitaceTaky 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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #158 kdy: 29. 08. 2018, 23:10:36 »
Citace od: Cikáda kdy 29. 08. 2018, 23:02:06
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áš.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #159 kdy: 29. 08. 2018, 23:15:08 »
Citace od: lopata kdy 29. 08. 2018, 23:10:36
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

Bacsa

Re:Rychlost Haskell vs. C++
« Odpověď #160 kdy: 29. 08. 2018, 23:18:38 »
Citace od: andy kdy 29. 08. 2018, 22:36:14
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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #161 kdy: 29. 08. 2018, 23:19:28 »
Citace od: andy kdy 29. 08. 2018, 23:15:08
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.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #162 kdy: 29. 08. 2018, 23:27:01 »
Citace od: lopata kdy 29. 08. 2018, 23:19:28
Citace od: andy kdy 29. 08. 2018, 23:15:08
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

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.

Re:Rychlost Haskell vs. C++
« Odpověď #163 kdy: 29. 08. 2018, 23:28:03 »
Citace od: lopata kdy 29. 08. 2018, 23:10:36
Závisí ten můj kód někde na undefined behavior? Nezávisí.

Závisí na tom, že spadne.

Citace od: lopata kdy 29. 08. 2018, 23:10:36
Dělá věci tak, jak by se normálně dělat měly? Nedělá.

Aspoň že se přiznáš.

Citace od: lopata kdy 29. 08. 2018, 23:10:36
Může reálně nastat, že někoho napadne udělat podobnou věc? Může.

To není argument.

Citace od: lopata kdy 29. 08. 2018, 23:10:36
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.

Citace od: lopata kdy 29. 08. 2018, 23:10:36
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...

Citace od: lopata kdy 29. 08. 2018, 23:10:36
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...

Re:Rychlost Haskell vs. C++
« Odpověď #164 kdy: 29. 08. 2018, 23:30:40 »
Citace od: lopata kdy 29. 08. 2018, 23:19:28
Citace od: andy kdy 29. 08. 2018, 23:15:08
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...