Rychlost Haskell vs. C++

JSH

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


lopata

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

andy

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

JSH

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

v

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


lopata

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

JSH

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

lopata

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

lopata

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

JSH

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

lopata

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

andy

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

andy

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

lopata

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

andy

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