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.