Hledám knihy: Myslíme v C++ a v Javě

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #120 kdy: 14. 09. 2019, 18:53:31 »
Někteří diskutující píší, že by se neměly používat, protože jsou drahé, že by se měly používat návratové hodnoty.

Ehm, to tu někdo napsal?

Je snad logické, že se jich ptám, jak by to tedy řešili v C++ a Javě, kdyby nesměli výjimky používat. Nabízí se mi pouze kostrbatá řešení, které buď používají, anebo mají něco lepšího.

Na to ses ale doposud neptal.

Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.

To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.

Haskell prosím odlož stranou, bavíme se o objektových jazycích.

Odkdy?


Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #121 kdy: 14. 09. 2019, 19:09:05 »
Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.
To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.

Dvojice se používají např. v Golang. V C++ a Javě vy to působilo poněkud nepatřičně.

Referencovaný argument byl zamítnut kvůli side-effectu a jsem téhož názoru.

Zbývají výjimky, které nejsou drahé, jsou praktické a vcelku efektivně brání logickým špagetám (není potřebné "else"). Jen se nesmí zneužívat k flow-controll.

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #122 kdy: 14. 09. 2019, 19:18:49 »
Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.
To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.

Dvojice se používají např. v Golang. V C++ a Javě vy to působilo poněkud nepatřičně.

Nevím, co na auto [ ] = vypadá nepatřičně.

Referencovaný argument byl zamítnut kvůli side-effectu a jsem téhož názoru.

Takže teď je in nepoužívat cokoliv s vedlejšími efekty?

Zbývají výjimky, které nejsou drahé, jsou praktické a vcelku efektivně brání logickým špagetám (není potřebné "else"). Jen se nesmí zneužívat k flow-controll.

To je zase nepodložených tvrzení. 1) Nezbývají výjimky. 2) Pokud způsobí stack-unwinding, tak ano, jsou typicky významně dražší než návratová hodnota. 3) Nevím, proč by mělo být potřebné else.

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #123 kdy: 14. 09. 2019, 19:32:53 »
Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.
To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.
Dvojice se používají např. v Golang. V C++ a Javě vy to působilo poněkud nepatřičně.
Nevím, co na auto [ ] = vypadá nepatřičně.

Blbě se to používá ve výrazech.

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #124 kdy: 14. 09. 2019, 19:45:11 »
Zbývají výjimky, které nejsou drahé, jsou praktické a vcelku efektivně brání logickým špagetám (není potřebné "else"). Jen se nesmí zneužívat k flow-controll.

To je zase nepodložených tvrzení. 1) Nezbývají výjimky. 2) Pokud způsobí stack-unwinding, tak ano, jsou typicky významně dražší než návratová hodnota. 3) Nevím, proč by mělo být potřebné else.

Když místo výjimek použiješ návratovou hodnotu, tak musíš použít kolem ní dost bižuterie, aby se ti hodnoty nepomíchaly s chybovými stavy, takže se ceny vyrovnají. Výjimky jsou však výrazně přehlednější, protože jejich ošetření se nachází mimo výkonný kód.

A jako vždy: když neošetříš výjimku, tak se sama ozve. Neošetřený návratový kód bude zticha.


Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #125 kdy: 14. 09. 2019, 19:45:58 »
Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.
To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.
Dvojice se používají např. v Golang. V C++ a Javě vy to působilo poněkud nepatřičně.
Nevím, co na auto [ ] = vypadá nepatřičně.

Blbě se to používá ve výrazech.

Existuje first a second.

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #126 kdy: 14. 09. 2019, 20:08:08 »
Vždy radostu si tu počíst. Někdo slyšel haskellu a hnedka se už považuje za neobyčejného (nebo jaký je opak obyčejného?) vývojaře.  8)

Nechtěl bys to trochu rozvést? Ovládáš snad Haskell lépe než ti, kteří se tu o něm zmiňují? Pochlub se, rád se přiučím.

Diky, ale opravdu se tu s váma (tím myslí, tu zdejší spam "elitu") nechci poměřovat / spamovat. Jen jsem chtěl vypíchnout tu absorditu, jak jinak obyčejní programátoři (všichni tu lepíte nějaký informační systémy a neříkejte, že ne), se dokážou navážet do obyčejných prográmátorů.

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #127 kdy: 14. 09. 2019, 20:30:36 »
Vždy radostu si tu počíst. Někdo slyšel haskellu a hnedka se už považuje za neobyčejného (nebo jaký je opak obyčejného?) vývojaře.  8)
Nechtěl bys to trochu rozvést? Ovládáš snad Haskell lépe než ti, kteří se tu o něm zmiňují? Pochlub se, rád se přiučím.
Diky, ale opravdu se tu s váma (tím myslí, tu zdejší spam "elitu") nechci poměřovat / spamovat. Jen jsem chtěl vypíchnout tu absorditu, jak jinak obyčejní programátoři (všichni tu lepíte nějaký informační systémy a neříkejte, že ne), se dokážou navážet do obyčejných prográmátorů.

Nebýt této komunity, asi bych se o Haskellu nedozvěděl. Snad není špatně, když se jich občas zeptám jak ho používají? Sám používám převážně PHP a XSLT, ale nebráním se rozšiřování obzorů.

V čem tedy programuješ?

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #128 kdy: 14. 09. 2019, 20:55:09 »
Tak tedy uveď návratovou hodnotu funkce, která má vrátit string, ale selže. Zároveň chci vědět, proč selhala a za jakých okolností.
To je dost abstraktní zadání. Nicméně lze to řešit např. dvojicí, referencovaným argumentem i výjimkou. Možností je dost a situací, kdy je to které řešení lepší, nespočet.
Dvojice se používají např. v Golang. V C++ a Javě vy to působilo poněkud nepatřičně.
V Javě působí nepatřičně všechno. Ale C++ má n-tice přímo v syntaxi. I když lepší je použít optional nebo něco podobného, to je přímo v STL.

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #129 kdy: 14. 09. 2019, 21:08:42 »
Když místo výjimek použiješ návratovou hodnotu, tak musíš použít kolem ní dost bižuterie, aby se ti hodnoty nepomíchaly s chybovými stavy, takže se ceny vyrovnají. Výjimky jsou však výrazně přehlednější, protože jejich ošetření se nachází mimo výkonný kód.

A jako vždy: když neošetříš výjimku, tak se sama ozve. Neošetřený návratový kód bude zticha.
Když neošetříš výjimku, tak se zas tak moc neozve. V lepším případě to v runtime komplet zdechne. V horším případě cestou nahoru rozbije nějaký ten invariant a chytně ji nějaký obecný catch blok.
V novém C++ máme třeba [[nodiscard]], takže neošetřený návratový kód se ozve už při kompilaci.

Zásadní problém výjimek je IMO právě to, že jsou oddělené od výkonného kódu a nejsou vidět.
Při pohledu na cizí kód nevím, co může a nemůže házet. Psát tak, že může házet opravdu cokoliv se moc nedá. Minimálně úklid a nějaký "commit" úspěšně vypočítaných hodnot (v c++ je to třeba oblíbený vzor výpočet a pak noexcept swap) musí jít bez házení. Jinak není moc šance udržet nějaké invarianty, leda tak při chybě všechno zahodit a doufat že to GC zvládne všechno pouklízet. O nějaké "strong exception safety" se v takovém případě moc uvažovat nedá.
Výkonný kód a chyby v něm jsou logicky dost úzce svázané a když je to na dvou místech tak se může snáze stát, že se upraví jen jedno. Ošetření výjimečných chyb je, díky tomu že to nastává jen zřídka, ten nejmíň otestovaný a nejvíc zabugovaný kód.

Z mých zkušeností byly výjimky výhodné, pokud jsem chyby nechtěl řešit. Tak trochu strčit hlavu do písku a nechat ať si to volající přebere. Ve chvíli kdy jsem začal přemýšlet nad možnými chybami a co by se v takovém případě mělo stát byly výjimky dost nešikovné. Právě díky tomu, že jsem ty možné stavy musel rozseknout a řešit na dvou místech.
« Poslední změna: 14. 09. 2019, 21:10:30 od Jiří Havel »

Kit

  • *****
  • 704
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #130 kdy: 14. 09. 2019, 21:29:57 »
Když místo výjimek použiješ návratovou hodnotu, tak musíš použít kolem ní dost bižuterie, aby se ti hodnoty nepomíchaly s chybovými stavy, takže se ceny vyrovnají. Výjimky jsou však výrazně přehlednější, protože jejich ošetření se nachází mimo výkonný kód.

A jako vždy: když neošetříš výjimku, tak se sama ozve. Neošetřený návratový kód bude zticha.
Když neošetříš výjimku, tak se zas tak moc neozve. V lepším případě to v runtime komplet zdechne. V horším případě cestou nahoru rozbije nějaký ten invariant a chytně ji nějaký obecný catch blok.
V novém C++ máme třeba [[nodiscard]], takže neošetřený návratový kód se ozve už při kompilaci.

Zásadní problém výjimek je IMO právě to, že jsou oddělené od výkonného kódu a nejsou vidět.
Při pohledu na cizí kód nevím, co může a nemůže házet. Psát tak, že může házet opravdu cokoliv se moc nedá. Minimálně úklid a nějaký "commit" úspěšně vypočítaných hodnot (v c++ je to třeba oblíbený vzor výpočet a pak noexcept swap) musí jít bez házení. Jinak není moc šance udržet nějaké invarianty, leda tak při chybě všechno zahodit a doufat že to GC zvládne všechno pouklízet. O nějaké "strong exception safety" se v takovém případě moc uvažovat nedá.
Výkonný kód a chyby v něm jsou logicky dost úzce svázané a když je to na dvou místech tak se může snáze stát, že se upraví jen jedno. Ošetření výjimečných chyb je, díky tomu že to nastává jen zřídka, ten nejmíň otestovaný a nejvíc zabugovaný kód.

Z mých zkušeností byly výjimky výhodné, pokud jsem chyby nechtěl řešit. Tak trochu strčit hlavu do písku a nechat ať si to volající přebere. Ve chvíli kdy jsem začal přemýšlet nad možnými chybami a co by se v takovém případě mělo stát byly výjimky dost nešikovné. Právě díky tomu, že jsem ty možné stavy musel rozseknout a řešit na dvou místech.

Tak to máme s výjimkami opačné zkušenosti. Neošetřené výjimky se mi krásně ozývají už v testech a vzhledem k tomu, že mají společného rodiče, vím přesně co může házet. V C++ je to jinak - výjimky mohou být jakéhokoli typu a proto je v tom bordel, který popisuješ. O schopnostech GC nemám pochybnosti.

Výjimečné chyby ošetříš o pár pater výš a vhledem k jednotnému rozhraní v tom nevidím žádný problém. Granularitu lze kdykoli zjemnit odchycením výjimky a uložením do stacku nové výjimky na vyšším levelu. Tím si zdroj výjimky krásně vytrasuješ.

Když upravíš jen kód nebo ošetření výjimek, tak tě na to testy hned upozorní. Toho bych se nebál.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #131 kdy: 14. 09. 2019, 23:15:21 »
Zásadní problém výjimek je IMO právě to, že jsou oddělené od výkonného kódu a nejsou vidět.
Při pohledu na cizí kód nevím, co může a nemůže házet.

+1

Chtělo by to něco do syntaxe, kterou by se dalo jasně specifikovat jaké výjimky to může házet. Skutečnost v Javě, kdy musíš definovat co ti to vrátí za výsledek, ale nemusíš definovat co ti to háže za výjimky mi přijde takové nekonzistentní.

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #132 kdy: 14. 09. 2019, 23:21:04 »
Tak to máme s výjimkami opačné zkušenosti. Neošetřené výjimky se mi krásně ozývají už v testech a vzhledem k tomu, že mají společného rodiče, vím přesně co může házet. V C++ je to jinak - výjimky mohou být jakéhokoli typu a proto je v tom bordel, který popisuješ. O schopnostech GC nemám pochybnosti.
Jak mi bázová třída pomůže v tom poznat, jestli nějaká funkce může házet nebo ne? A ta javovská Exception je tak generická, že vím přesně akorát to, že to zvládnu zalogovat. Do teď jsem měl pocit, že se bavíme o primárně produkci. Pokud mám nějakou situaci pokrytou testy, tak mi chytí i zapomenutý test na návratovou hodnotu. Ale ty zapomenuté situace už z principu těmi testy moc pokryté nebývají.

V C++ je to úplně na stejno, protože v praxi nikdo nehází nic, co by nebylo odvozené od std::exception. Inty a podobné věci se házejí akorát v (mizerných) ukázkových prográmcích.

Já o schopnostech GC pochybnosti mám. Protože to, co je opravdu třeba uklidit rychle je právě "nepaměťový" binec. Soubory, sockety a další takové věci. Když po chycení chyby zůstane (potenciálně dost dlouho) viset zamčený soubor nebo otevřený socket, tak to není úplně OK.
Citace
Výjimečné chyby ošetříš o pár pater výš a vhledem k jednotnému rozhraní v tom nevidím žádný problém. Granularitu lze kdykoli zjemnit odchycením výjimky a uložením do stacku nové výjimky na vyšším levelu. Tím si zdroj výjimky krásně vytrasuješ.
Jednotné rozhraní čeho? Neznámou Exception můžu akorát tak převést na neznámý řetězec, ten zalogovat a pak zdechnout. To už můžu zavolat při jakékoliv chybě rovnou abort. V tom crashdumpu ten callstack dostanu taky.

To "ošetříš" znamená kód, který se díky tomu "výjímečné" moc často nespouští. Je opravdu dobře otestovaný? Netestují se náhodou jen běžné chyby?
Citace

Když upravíš jen kód nebo ošetření výjimek, tak tě na to testy hned upozorní. Toho bych se nebál.
Teoreticky jo. Ale v praxi jsou ty testy kapku míň spolehlivé. Testuje se to, co někoho napadne, nebo co už se jednou vymamlasilo. Na nečekané chyby testy nejsou.

Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #133 kdy: 14. 09. 2019, 23:28:44 »
Chtělo by to něco do syntaxe, kterou by se dalo jasně specifikovat jaké výjimky to může házet. Skutečnost v Javě, kdy musíš definovat co ti to vrátí za výsledek, ale nemusíš definovat co ti to háže za výjimky mi přijde takové nekonzistentní.
Snaha byla. V c++ se může u funkce specifikovat throws(...), v Javě jsou checked exceptions. C# měl ty checked exceptions taky, ale vyhodil je. V javě se od nich pokud vím taky upouští. A v c++ to byl taky fail.

Nevím o jazyce, kde by se to fungovalo rozumně. Všude se pokud vím přešlo na jednodušší nehází/hází cokoliv.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Hledám knihy: Myslíme v C++ a v Javě
« Odpověď #134 kdy: 14. 09. 2019, 23:57:21 »
Zásadní problém výjimek je IMO právě to, že jsou oddělené od výkonného kódu a nejsou vidět.
Při pohledu na cizí kód nevím, co může a nemůže házet.

+1

Chtělo by to něco do syntaxe, kterou by se dalo jasně specifikovat jaké výjimky to může házet. Skutečnost v Javě, kdy musíš definovat co ti to vrátí za výsledek, ale nemusíš definovat co ti to háže za výjimky mi přijde takové nekonzistentní.
Ono také záleží na tom, jaké výjimky mohou nastat. Force majeure (například “file not found” nebo “out of memory”) se nedá předpokládat (=odchytit při typové kontrole), kdežto takové “index out of bounds” není force majeure, protože to umí eliminovat závislostní typy. Čím méně výjimek je přípustných, tím snazší je explicitně je specifikovat. Otázka pak jen je, jestli má smysl se s nimi otravovat, když kombinace silného (závislostního) systému a maybe pro nepředvídatelné výjimečné situace vede k přehlednějšímu kódu.