Rychlost Haskell vs. C++

lopata

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


lopata

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

andy

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

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

andy

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


lopata

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

lopata

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

andy

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

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

lopata

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

lopata

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

v

Re:Rychlost Haskell vs. C++
« Odpověď #116 kdy: 28. 08. 2018, 23:13:05 »
FYI ghc a haskell není to samé

v

Re:Rychlost Haskell vs. C++
« Odpověď #117 kdy: 28. 08. 2018, 23:15:19 »
hmm překlad C/C++ modulu s "nevhodným" --std=

andy

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

lopata

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