Rychlost Haskell vs. C++

Radek

Re:Rychlost Haskell vs. C++
« Odpověď #150 kdy: 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.


Re:Rychlost Haskell vs. C++
« Odpověď #151 kdy: 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 :)

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #152 kdy: 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

andy

Re:Rychlost Haskell vs. C++
« Odpověď #153 kdy: 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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #154 kdy: 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í.


v

Re:Rychlost Haskell vs. C++
« Odpověď #155 kdy: 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?

Re:Rychlost Haskell vs. C++
« Odpověď #156 kdy: 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.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #157 kdy: 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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #158 kdy: 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áš.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #159 kdy: 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

Bacsa

Re:Rychlost Haskell vs. C++
« Odpověď #160 kdy: 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.

lopata

Re:Rychlost Haskell vs. C++
« Odpověď #161 kdy: 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.

andy

Re:Rychlost Haskell vs. C++
« Odpověď #162 kdy: 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
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.

Re:Rychlost Haskell vs. C++
« Odpověď #163 kdy: 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...

Re:Rychlost Haskell vs. C++
« Odpověď #164 kdy: 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...