Jak můžu opustit funkci

Kiwi

Re:Jak můžu opustit funkci
« Odpověď #210 kdy: 17. 07. 2018, 13:03:18 »
Ale já stále nechápu, proč by "chybový stav" měl být nějak privilegovaný oproti jakémukoli jinému "normálnímu" stavu.
Protože se na něj reaguje úplně jinak, než na normální stav. Pokud je stav normální, pokračuje program normálně v běhu. Pokud je stav chybový, může se program pokusit z něj nějak zotavit a vrátit program do nějakého normálního (předchozího nebo základního) stavu.

Představte si to třeba na bezpečných systémech. Když zabezpečovací systém na soupravě metra detekuje, že došlo k překročení maximální povolené rychlosti, nemůže se to řešit jako ostatní stavy, kde se řeší optimalizace rychlosti vzhledem k profilu tratě, grafikonu, cílovému brzdění atd. – nemůže tam mezi tím vším být schovaná podmínka „jo a pokud je překročená maximální rychlost, asi by bylo fajn začít brzdit“. Ne, ten chybový stav musí mít před vším přednost, všechno ostatní se zahodí a začne se řešit ten chybový stav – maximálním brzděním. A řešení toho chybového stavu skončí až tehdy, když je systém v nějakém jasně definovaném bezpečném stavu. Což by mohl být třeba návrat pod křivku maximální rychlosti, ale třeba v pražském metru je ten bezpečný stav až úplné zastavení soupravy. Teprve když souprava stojí, vrátila se do bezpečného normálního stavu, zruší se řešení chybového stavu a je možné pokračovat normálním způsobem, tj. strojvedoucí může soupravu znovu rozjet.
Ale tohle je přece něco naprosto jiného! Tady se bavíme o výjimkách jakožto syntaktické konstrukci v jazyce. Ne o výjimkách jakožto přerušení hlavního programu hardwarem. Pokud bude na dané platformě přerušovací systém, tak se takovéto výjimečné stavy vyřeší přes něj. Pokud tam nebude, tak opět nezbývá než "ruční" testování jako by to byl "normální" stav. Jakožto celoživotní embedded vývojář už jsem se setkal s oběma možnostmi - různé ASICy žádný přerušovací systém nemají a skutečně v takových případech nezbývá nic jiného než testovat to jako běžnou podmínku - jen je třeba myslet na to, kdy bude testovaná a jak dlouho bude trvat, než se program dostane k obsluze takového stavu. Jak v tomhle pomohou výjimky v jazyku?

Když chci otevřít soubor, který neexistuje - proč bych to měl ošetřovat někde jinde? Když nedostanu požadovanou paměť, když v parseru detekuji syntax error
Třeba proto, abyste tu chybu vůbec ošetřil. Nebo protože jí potřebujete ošetřit na místě, kde ji vůbec nějak ošetřit můžete – což vůbec nemusí být místo, kde vznikla. Výjimky vám nebrání ošetřit chybu hned v místě, kde vznikla – ale nenutí vás k tomu. Pochybuju, že doopravdy ošetřujete možné chyby všude tam, kde teoreticky mohou nastat. Třeba při alokaci paměti.
Fragmenty typu if ((m = malloc(...))) nebo if ((f = fopen(...))) považuju za céčkové idiomy. Existují samozřejmě i chyby v alokaci jiného typu (lokální automatická data), ale to opět principiálně s jazykovými výjimkami nesouvisí. Chyba se nejlépe ošetřuje právě tam, kde vzniká. A pokud to nelze, propaguju ji výše jako chybu na úrovni vrstvy, která se s ní naposledy nedokázala vyrovnat. Ty na hlídání alokací kašleš?

Záleží na typu komunikačního protokolu. Z transportní vrstvy bych měl obdržet celistvou zprávu, bez chyb. Pokud je v ní chyba, je to jasná výjimka. Pokud je chybný datový paket mezi transportní a síťovou vrstvou, je to jen stav, protože může běžně nastat.
Taková chyba principiálně nemůže nestat. Transportní vrstva dodá buď bezchybnou zprávu, nebo nějakou chybu typu timeout při příjmu. Ale co je na tom výjimečného? To je na transportní vrstvě zrovna tak "normální" stav, jako poškozená zpráva na síťové vrstvě.



Re:Jak můžu opustit funkci
« Odpověď #211 kdy: 17. 07. 2018, 13:09:28 »
Ale já stále nechápu, proč by "chybový stav" měl být nějak privilegovaný oproti jakémukoli jinému "normálnímu" stavu.
Protože se na něj reaguje úplně jinak, než na normální stav. Pokud je stav normální, pokračuje program normálně v běhu. Pokud je stav chybový, může se program pokusit z něj nějak zotavit a vrátit program do nějakého normálního (předchozího nebo základního) stavu.

Představte si to třeba na bezpečných systémech. Když zabezpečovací systém na soupravě metra detekuje, že došlo k překročení maximální povolené rychlosti, nemůže se to řešit jako ostatní stavy, kde se řeší optimalizace rychlosti vzhledem k profilu tratě, grafikonu, cílovému brzdění atd. – nemůže tam mezi tím vším být schovaná podmínka „jo a pokud je překročená maximální rychlost, asi by bylo fajn začít brzdit“. Ne, ten chybový stav musí mít před vším přednost, všechno ostatní se zahodí a začne se řešit ten chybový stav – maximálním brzděním. A řešení toho chybového stavu skončí až tehdy, když je systém v nějakém jasně definovaném bezpečném stavu. Což by mohl být třeba návrat pod křivku maximální rychlosti, ale třeba v pražském metru je ten bezpečný stav až úplné zastavení soupravy. Teprve když souprava stojí, vrátila se do bezpečného normálního stavu, zruší se řešení chybového stavu a je možné pokračovat normálním způsobem, tj. strojvedoucí může soupravu znovu rozjet.
Ale tohle je přece něco naprosto jiného! Tady se bavíme o výjimkách jakožto syntaktické konstrukci v jazyce. Ne o výjimkách jakožto přerušení hlavního programu hardwarem. Pokud bude na dané platformě přerušovací systém, tak se takovéto výjimečné stavy vyřeší přes něj. Pokud tam nebude, tak opět nezbývá než "ruční" testování jako by to byl "normální" stav. Jakožto celoživotní embedded vývojář už jsem se setkal s oběma možnostmi - různé ASICy žádný přerušovací systém nemají a skutečně v takových případech nezbývá nic jiného než testovat to jako běžnou podmínku - jen je třeba myslet na to, kdy bude testovaná a jak dlouho bude trvat, než se program dostane k obsluze takového stavu. Jak v tomhle pomohou výjimky v jazyku?

Pokud resis ASIC bez preruseni, tak vyjimky skutecne asi nejsou ta uroven abstrakce, ktera te zajima...

Pro mainstreamove/aplikacni programovani je to neocenitelny konstrukt.

Kiwi

Re:Jak můžu opustit funkci
« Odpověď #212 kdy: 17. 07. 2018, 13:20:07 »
Po pravdě, sice takový kód nesnáším, ale dám se podat. True a false naprosto běžně v C definuji přes makra a nikdy jsem s tím žádný problém neměl. Nějaké tušení, na co asi narážíš, sice mám, ale jestli je to skutečně ono, tak problém bude kapku jinde.

A je `x == true` to same jako `x`? ;-)
Pokud nevím, jak je definované true, tak se na to dá dost těžko odpovědět.

Btw, teď jsem viděl od kontraktora
Kód: [Vybrat]
if (x == true) {...} else if (x == false) {...}
Nezabil bys ho za ty dvě chyby?

Tento zápis představuje třícestné rozbočení. Bez dalšího vysvětlení je obtížné pochopit, o co jde a proto je to špatně.

O toto mu asi ide:
1.  v C nie je hodnota pre true definovana, moze byt vsetko okrem 0. To je prvy problem.  Ak pouzivas standardnu libku, alebo si normalny( das true = 1 a false = 0), tak nie je problem.  Alebo si predposraty a das tam if(x != false).
2. ozaj je to trojcestne rozhodovanie.

Normální céčkař definuje false jako 0 a true jako negaci false a programuje s vědomím, že false je nula a nenula je true. Testovat na true je nešvar snad v kterémkoli jazyce, ale nemusí jít nutně o chybu. Při použití standardních knihoven to chyba je, ale v konzistentním kódu bez cizího kódu nemusí. Jinak souhlasím s tím, že to obecně není správné takto testovat - jak jsem ostatně napsal hned v prvním postu k tomu.

balki

Re:Jak můžu opustit funkci
« Odpověď #213 kdy: 17. 07. 2018, 13:35:29 »
Normální céčkař definuje false jako 0 a true jako negaci false a programuje s vědomím, že false je nula a nenula je true. Testovat na true je nešvar snad v kterémkoli jazyce, ale nemusí jít nutně o chybu. Při použití standardních knihoven to chyba je, ale v konzistentním kódu bez cizího kódu nemusí. Jinak souhlasím s tím, že to obecně není správné takto testovat - jak jsem ostatně napsal hned v prvním postu k tomu.

Ako v ktorom jazyku. V jave mas okrem primitivneho boolean aj objekt Boolean a to je trojhodnotove. Moze nadobudnut hodnotu Boolean.TRUE, Bollean.False a null.  A teraz babo rad.  Co je null?  Chyba? False? True?

Re:Jak můžu opustit funkci
« Odpověď #214 kdy: 17. 07. 2018, 13:36:07 »
Po pravdě, sice takový kód nesnáším, ale dám se podat. True a false naprosto běžně v C definuji přes makra a nikdy jsem s tím žádný problém neměl. Nějaké tušení, na co asi narážíš, sice mám, ale jestli je to skutečně ono, tak problém bude kapku jinde.

A je `x == true` to same jako `x`? ;-)
Pokud nevím, jak je definované true, tak se na to dá dost těžko odpovědět.

Ale muzes... (resp. daleko podstatnejsi je to, jak vznikne x, nez to, jak kdo definoval true)


JSH

Re:Jak můžu opustit funkci
« Odpověď #215 kdy: 17. 07. 2018, 13:37:52 »
Fragmenty typu if ((m = malloc(...))) nebo if ((f = fopen(...))) považuju za céčkové idiomy. Existují samozřejmě i chyby v alokaci jiného typu (lokální automatická data), ale to opět principiálně s jazykovými výjimkami nesouvisí. Chyba se nejlépe ošetřuje právě tam, kde vzniká. A pokud to nelze, propaguju ji výše jako chybu na úrovni vrstvy, která se s ní naposledy nedokázala vyrovnat. Ty na hlídání alokací kašleš?
Kašlat na kontrolu alokací může být podle platformy i racionální návrhové rozhodnutí.

Na Windowsech a Linuxech s overcommitem se alokace hlídají docela blbě. malloc samotný selže leda tak v případě, že dostane jako parametr úplnou blbost. Jinak OS akorát přidělí virtuální paměť. Fyzická se přiděluje až při pokusu o zápis. A tam může nastat několik možností (podle druhu a nastavení OS):
- Program se uswapuje k smrti.
- Pokus o zápis do úspěšně alokované paměti skončí segfaultem.
- Swaper to natvrdo zabije.

Troufnu si tvrdit, že drtivé většině PC programátorů selhal malloc akorát v případě, kdy blbě spočítali velikost.

Re:Jak můžu opustit funkci
« Odpověď #216 kdy: 17. 07. 2018, 13:41:29 »
Ako v ktorom jazyku. V jave mas okrem primitivneho boolean aj objekt Boolean a to je trojhodnotove. Moze nadobudnut hodnotu Boolean.TRUE, Bollean.False a null.  A teraz babo rad.  Co je null?  Chyba? False? True?

To neni zadne babo rad... null neni chyba, True ani False. Je to null. Jeho chovani je celkem dobre definovane, kdyz se dostanes do situace, ze bys ho unboxoval, dostanes NPE.

Kód: [Vybrat]
java> Boolean a = null;
java.lang.Boolean a = null
java> if (a) System.out.println(a);
java.lang.NullPointerException

Asi nema smysl zduraznovat, ze nullable hodnoty jsou problematicke samy o sobe a ze uz nejaky ten patek mame optional, ktery celkem jasne vyjadruje myslenku, ze existuje moznost, ze tam dana vec nebude.

kkt1

  • *****
  • 796
    • Zobrazit profil
Re:Jak můžu opustit funkci
« Odpověď #217 kdy: 17. 07. 2018, 13:59:42 »
Nevite nekdo jestli uz tu funkci po 200 prispevcich opustil?

Re:Jak můžu opustit funkci
« Odpověď #218 kdy: 17. 07. 2018, 14:12:13 »
Ale tohle je přece něco naprosto jiného! Tady se bavíme o výjimkách jakožto syntaktické konstrukci v jazyce. Ne o výjimkách jakožto přerušení hlavního programu hardwarem.
Nevím, co je naprosto jiného, protože já píšu právě o výjimkách jakožto syntaktické konstrukci v jazyce a odpovídající implementaci v přeloženém kódu.

Fragmenty typu if ((m = malloc(...))) nebo if ((f = fopen(...))) považuju za céčkové idiomy. Existují samozřejmě i chyby v alokaci jiného typu (lokální automatická data), ale to opět principiálně s jazykovými výjimkami nesouvisí.
Ano, jsou to céčkové idiomy, ale to bohužel nezaručuje, že nenajdete kód bez toho ošetření. S jazykovými výjimkami to souvisí tak, že v céčku chybový stav můžete zachytit, když chcete – a když ne, tak chybu typicky hned v následujícím řádku kódu zazdíte. Výjimky jako jazyková konstrukce zajišťují, že nemůžete pouhým opomenutím chybový stav ignorovat – pokud výjimku neošetříte, probublá až někam do hlavní metody a (typicky) ukončí program. Pokud chcete takovou výjimku zazdít, musíte se aspoň trochu snažit.

Chyba se nejlépe ošetřuje právě tam, kde vzniká.
To vůbec není pravda. Místo vzniku výjimky a místo jejího ošetření spolu nijak nesouvisí – někdy to může být to samé místo, někdy je to někde úplně jinde.

Ty na hlídání alokací kašleš?
Ne. A výjimky mi dost usnadňují na něj nekašlat.

Taková chyba principiálně nemůže nestat. Transportní vrstva dodá buď bezchybnou zprávu, nebo nějakou chybu typu timeout při příjmu. Ale co je na tom výjimečného? To je na transportní vrstvě zrovna tak "normální" stav, jako poškozená zpráva na síťové vrstvě.
Výjimky nejsou výjimečné tím, že by k nim docházelo výjimečně málo často, ale tím, že je to výjimka z normálního běhu programu, odchylka od toho, co chci, aby program dělal. K chybám při síťovém transportu může docházet hodně často, ale program je dělaný proto, aby data úspěšně přenášel – neúspěšný přenos je odchylka od tohoto žádaného stavu, proto je to výjimka.

balki

Re:Jak můžu opustit funkci
« Odpověď #219 kdy: 17. 07. 2018, 14:19:24 »
Ako v ktorom jazyku. V jave mas okrem primitivneho boolean aj objekt Boolean a to je trojhodnotove. Moze nadobudnut hodnotu Boolean.TRUE, Bollean.False a null.  A teraz babo rad.  Co je null?  Chyba? False? True?

To neni zadne babo rad... null neni chyba, True ani False. Je to null. Jeho chovani je celkem dobre definovane, kdyz se dostanes do situace, ze bys ho unboxoval, dostanes NPE.

Kód: [Vybrat]
java> Boolean a = null;
java.lang.Boolean a = null
java> if (a) System.out.println(a);
java.lang.NullPointerException

Asi nema smysl zduraznovat, ze nullable hodnoty jsou problematicke samy o sobe a ze uz nejaky ten patek mame optional, ktery celkem jasne vyjadruje myslenku, ze existuje moznost, ze tam dana vec nebude.

To je sice pekne, ale predstav si, ze chces podla toho objektoveho Booleana vetvit kod. Das tam

if(!Boolean.FALSE.equals(x) ){

}

No ale to mas prdlajz a nie spravne vyhodnotene, lebo tam moze byt aj null.

Nepomoze ani:
if( x != false ){

}

a taktiez je mozny uz spominany nullpointer

if (x){

}

Optional je len posunutie problemu inam. Lebo to je zasa trojhodnotove - nedefinovane, true, false.

Treba to citat v kontexte prispevku, na ktory som reagoval povodne.

balki

Re:Jak můžu opustit funkci
« Odpověď #220 kdy: 17. 07. 2018, 14:21:00 »
Nevite nekdo jestli uz tu funkci po 200 prispevcich opustil?

Funkcia sa uz obesila na luster.

Kit

Re:Jak můžu opustit funkci
« Odpověď #221 kdy: 17. 07. 2018, 14:34:06 »
To je sice pekne, ale predstav si, ze chces podla toho objektoveho Booleana vetvit kod. Das tam
Kód: [Vybrat]
if(!Boolean.FALSE.equals(x) ){
}
No ale to mas prdlajz a nie spravne vyhodnotene, lebo tam moze byt aj null.

Je mnoho důvodů, proč nepoužívám proměnné typu boolean. Vystačím si s tímto:
Kód: [Vybrat]
if (isX()) {
...
}

.

Re:Jak můžu opustit funkci
« Odpověď #222 kdy: 17. 07. 2018, 15:29:47 »
Pro mainstreamove/aplikacni programovani je to neocenitelny konstrukt.
A proto nové jazyky jako Rust nebo Go výjimky nemají?

Re:Jak můžu opustit funkci
« Odpověď #223 kdy: 17. 07. 2018, 15:46:13 »
Pro mainstreamove/aplikacni programovani je to neocenitelny konstrukt.
A proto nové jazyky jako Rust nebo Go výjimky nemají?

Go je odpad.
A Rust má docela pěkné řešení ve stylu Left/Right, ale docela by mě zajímalo, jak to bude škálovat, když se člověk pustí do nějakého aplikačního vývoje a ne jen low-level.

Re:Jak můžu opustit funkci
« Odpověď #224 kdy: 17. 07. 2018, 15:48:19 »

To je sice pekne, ale predstav si, ze chces podla toho objektoveho Booleana vetvit kod. Das tam
Kód: [Vybrat]
if(!Boolean.FALSE.equals(x) ){
}
No ale to mas prdlajz a nie spravne vyhodnotene, lebo tam moze byt aj null.

Je mnoho důvodů, proč nepoužívám proměnné typu boolean. Vystačím si s tímto:
Kód: [Vybrat]
if (isX()) {
...
}


A když potřebuješ výsledek toho isX() vícekrát? (Ptám se pro kamaráda, co má v tom isX() přístup ke clusteru.)