Je to otázka názoru. Mě se ten jejich masochismus prostě líbí, protože to zabraňuje lidem dělat prasárny. Už jsem měl tu čest se 700 řádky obalenými try/exceptem. Lidé jsou líní. Navíc, když už člověk ošetřuje error tak si to většinou rovnou i srozumitelně logne => lépe se to potom debuguje než nějaká generická hláška. Chtělo by to jen kratší zápisy těch error checků a na tom snad už pracují. Je plno věcí co go má a jiné jazyky zase nemají. Třeba takový defer budou Pythonáři hledat marně. Built-in testy/profilování/benchmarky a dokumentace přes comment markdown je taky užasná věc.
defer funkcionalitu nebudou hledat marně ani pythonisti (context managers [1]) ani javisti (try-with-resources [2]). Oba jazyky maji trošku jiný zápis toho samého s explicitním vyznačením bloku platnosti (u defer je to funkce).
Defer je jinak pěkný, ale taky se s ním musí opatrně.
[1] třeba tady https://jeffknupp.com/blog/2016/03/07/python-with-context-managers/
[2] https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Jestli chapu spravne vyuziti defer v Go, je to v podstate nahrada try-finally (coz ma treba Python snad odjakziva), protoze, ted pozor, Go vyjimky nema, protoze nejsou potreba. Ale jasne, zase soudruzi v Go vynalezli kolo. Context manager (with) je kvalitativne o uroven vys.
Defer není úplně to samé jako jednoduché finally, i když je mu hodně blízko.
Defer funkce se totiž dá zaregistrovat až ve chvíli, kdy je co uklízet. Čímž řeší problém alokace více zdrojů s kontrolou selhání a úklidem v každém kroku. Finally si naopak musí samo zjistit co uklidit a co se už nezvládlo vytvořit.
Myslím si, že právě proto jsou with a try-with-resources tomu defer sémanticky nejblíž. Všechno je to syntaktický cukr, který programátorovi umožňuje po sobě uklidit a přitom neřešit jak a kdy blok/funkce skončí.
Souhlas, absence vyjimek a mizerna standardni knihovna je momentalne nejvetsi bolest golangu.
A pokud to nefixnou, golang na to zdechne.
Fakt nechapu, co ma byt jako problem.
A kdyz si clovek precte "zduvodneni" proc jako vyjimky ne, zacne pochybovat o dusevnim zdravi autoru:
https://golang.org/doc/faq#exceptions
Vzdyt je to prevelika krasa, po kazdem zavolani funkce pridat boilerplate checku:
Toto je z ofic go blogu. Pise se rok 1981 a vsude se tanci twist.
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
dst, err := os.Create(dstName)
if err != nil {
return
}
written, err = io.Copy(dst, src)
dst.Close()
src.Close()
return
}
Protože lidi začali používat výjimky pro ne úplně výjimečné stavy. Např. nechápu, proč bych měl vyhazovat výjimku při něčem tak očekávaném jako "soubor nenalezen" - to už je masochizmus. Pokud se bavíme o nějakém zjednodušení control-flow při výskytu chyby tak tam nemám nic proti tomu přizpůsobit tomu trochu jazyk nebo použít nějaký construct typu Result<>, Maybe<> atd. Problém Go je v tom, že nemá podporu generiky, takže to asi bude muset řešit nějak jinak, ale nesleduju to, protože staticky typovaný jazyk bez generiky me nezajímá (a navíc když vidím ten Go kód, tak mi to přijde jak pascal a bez těch středníků je takový smutný :).
Jinak trochu víc k věci. Např. Rust výjimky nemá a tomu jazyku to nijak nechybí - obecně pro multithread aplikace je to možná ten nejlepší přístup. V C++ komunitě se teď taky začalo diskutovat o tom, že by mělo dojít k přepracování výjimek, protože ten design není ok a dopad na výkon zpracování jednoho stavu navíc se stejně blíží nule (nechci se rozepisovat, toto bude stejně trvat dlouho, ale už jen to, že někdo připustil že máme problém, je celkem výhra).
Jinak to byl tak trochu troll-post pro ty co dávají rádi minus :)
@unicode
Ode mne mínus nemáš, sorry. Nevím jak je to v Rustu, takže to nekomentuju. Ptám se proto, protože nedávno jsem řešil aplikaci bez vyjímek a není skutečně nic lepšího než vracet přes zanoření šesti funkcí nejaký objekt (či něco) s errory, předávat ho mezi všemi třídami či funkcemi a po každém každičkém volání funkce kontrolovat jestli neskončila errorem, případně jakým, to se ani nebavím o externích knihovnách a jejich takových objektech. Ostatně takto je napsaná půlka všemi milovaného Wordpresu. To je můj pohled. Pletu se? Tak se rád přiučím - proto se ptám.
Já dělám hlavně v C/C++, js (node), a trochu se zajímám o rust. Vyhýbám se PHP a Javě. Bez pohledu na konkrétní kód je podle mě těžké se bavit o tom, jaký přístup je lepší nebo co by se dalo zlepšit. Použití výjimek záleží i na tom, ve kterém jazyce člověk dělá. Např. v C++ hodně záleží na projektu i na tom, které knihovny ten projekt používá.
Osobně si myslím, že exceptions nejsou silver bullet a člověk, který je chce používat úplně na všechno je jak to dítě s tím kladivem co vidí všude jen hřebíky :)
Jenomže výjimkou jsou silver bullets. Je řada stavů, které bez výjimek prostě rozumně neošetříte. Proto výjimky existují už na úrovni procesoru a strojového kódu, kde se jim říká přerušení.
Jazyky na hraní, jako je Go, to nikdy nezjistí. Ale jazyky, které mají zajistit nějakou spolehlivost se bez výjimek neobejdou.
Zdrojem chyb může být miliarda věcí od hardware, operačního systému, momentálních potíží v alokaci zdrojů, různých existujících/neexistujících práv kdekoli - a miliarda dalších věcí. I při otevírání souboru může docházet pamět, docházet místo na zásobníku, dojít k hardwarové chybě disku, mít problémy s právy, atd.
Za 30 let programátorské praxe jsem ještě nikdy neviděl dobře ošetřený kód bez výjimek ani při takové kravině, jako je otevírání souboru. Kód, který by skutečně kvalitně ošetřoval všechny možnosti. Nehledě k tomu, že různé chyby by se měly ošetřovat často na různých místech - ne vše může rozumně ošestřit ten, kdo volá fopen().
Většinou osoby zastávající nepoužívání výjimek končí tak, že většina lidí prostě chyby ignoruje. Počítá s tím, že nenastanou. Nebo je ošetřují jen někde. K nahlédnutí v tisících open source zdrojových kódech.
Vzpomínám si na to, jak programovací jazyk Ada urychleně přidával do nové normy výjimky. Zjistilo se, že ty sw prostě padají při řadě situací, a programátor bez výjimek s tím nic neudělá. Program při řadě chyb mohl jen udělat terminate(), a poslat do šrotu pár miliónů či miliard dolarů v družici kdesi mimo zemi. Najednou byly všechny námitky proti výjimkám bezpředmětné. A najednou šly ošetřit všechny stavy, a něco udělat.
Proboha jak mohlo být dopuštěno, že fungují embedded systémy (zdravotnictví, doprava, energetika, ... - většina PLC a to i řada speciálních "žlutých" emergency stop systémů), na kterých závisí životy a jsou implementované v ANSI C bez výjimek ?
Jak to, že jaderné elektrárny jsou řízeny Fortan kódem bez výjimek ?
Jak to, že vojenské zbraňové systémy jsou řízeny kódem bez výjimek ?
Proč toho je tolik bez "rozumného ošetření" ?
Jaký je zásadní rozdíl mezi kódem, který rozhoduje co s chybou (zpracovat, zkusit znovu, počkat, poslat výše, ...) s pomocí paradigma/syntaxe:
a) if/switch ...
b) try/catch ...
?
Zásadní mi přijde u try/catch proti if/switch možnost nepovšimnutého "probublání" chyb spodnějších slupek (knihoven) API do hornějších vrstev aniž hornější slupky vrstvených API mají tušení (resp. programátoři, kteří je používají), že se něco takového dole může stát a proto je to často "nahoře" chybně ošetřeno. Tedy pokud není v každé úrovni slupky postupováno s vědomým o možných stavech/chybách, čemuž přesně try/catch napomáhá.
Malý příklad, kdysi jsem potkal Python knihovnu pro čtení GPS. A stalo se, že implementátor navazujícího API si řekl, když čtení GPS vrací výjimku, stačí GPS reinicializovat a "ono se to spraví", to bude problém komunikace. "se to" má často zásadní roli u úvah tohoto typu ;-) Inu jakmile se GPS ocitla na druhé polokouli, tak toto "ošetření výjimky" se zcela míjelo účinkem, protože problém byl v chybném zpracování záporných WGS souřadnic.
Jsem "analfabet", co neumí číst a chápat řadu textů, na tom asi není nic objevného, proto mám takové pitomé otázky.
Proč u těchto systémů, kde investujeme enormní námahu, aby se nevysypaly (a je tam brutální overengineering) ve většině případů nejsou použity výjimky k obsluze chybových stavů (když by výjimky měly být "silver bullets", efektivní a rychlé na obsluhu, prostě to bez nich rozumně neošetříte) ?
Proč výjimky nejsou úplně to pravé ořechové pro kritické systémy ?
Co znamená, že výjimky jsou vhodné pro systémy, které se mohou vysypat (kde nevěnujeme enormní námahu, aby se nevysypaly) ?
Proč připouštíme plánovaně vadný SW a jaké dopady to má na uživatele, společnost ?
We are programmers who aspire to be worthy of the title of Craftsman. So what is a software craftsman? What promises do software craftsmen make to their fellow craftsmen, their employers, and society at large? https://www.youtube.com/watch?v=17vTLSkXTOo
Michal Mühlpachr: Protože ty kritické systémy jsou navrhované tak, aby bylo u všech variant běhu předem jasné (tj. že tu variantu opravdu někdo promýšlel, ne jen deterministické), co přesně se stane. Tyto systémy jsou pro to malé a jednoduché, protože není v lidských silách takhle podrobně analyzovat komplexní systém. A mimochodem ani u těch kritických systémů se často nepočítá s tím, že by byly bezchybné, takže třeba vedle sebe běží dvě různé implementace, je tam bezpečný komparátor a když se obě implementace neshodnou na výsledku, přejde se do nějakého bezpečného stavu (např. se zastaví linka).
Vedle těchto kritických systémů ale také máme mnoho daleko komplexnějších systémů, u kterých prostě nedokážeme předem promyslet všechny stavy. A tam jsou výjimky velice užitečné, protože zajišťují to, že výjimečný stav není ignorován. Což je právě problém jazyků, kde se chyby řeší např. návratovou hodnotou, kterou programátor může ale nemusí zkontrolovat – a jakmile jí na tom správném místě nezkontroluje, na ten výjimečný stav se zapomene a program běží dál, jako by se nechumelilo, a vrší na sebe další a další chyby. Přičemž to, že programátor vy takovém případě nezkontroluje, zda nedošlo k chybě, je nejčastější situace. Zrovna nedávno se na Abíčku pod zprávičkou o portaci Sysinternals utilit na Linux rozběhla diskuse neprogramátorů o tom, jak je ten kód hrozný, protože pravděpodobně poprvé v životě viděli kód v C, kde je většina možných chybových stavů ošetřena.
Proč připouštíme plánovaně vadný SW a jaké dopady to má na uživatele, společnost ?
To s výjimkami nijak nesouvisí. A nedokonalý software připouštíme proto, že jakékoli další přiblížení dokonalosti je stále dražší a dražší, zatímco přidaná hodnota je stále nižší a nižší. Lidé totiž odjakživa žijí v nedokonalém světě, takže si s nedokonalostmi dokáží docela dobře poradit, a radši žijí v barácích, i když občas nějaký spadne, než aby žili dál na stromech a čekali, až budeme umět postavit dokonalé baráky (zvlášť když i u těch stromu se občas nějaká větev ulomí).
Snažím se od tvrzení:
> A moderni jazyk bez vyjimek, to mi prijde uplne mimo.
> absence vyjimek a ... je momentalne nejvetsi bolest golangu.
> Jenomže výjimkou jsou silver bullets. Je řada stavů, které bez výjimek prostě rozumně neošetříte.
posunout k "výjimky nejsou jediné nezbytné a zázračné" paradigma.
Domnívám se, že výjimky jdou proti srozumitelnosti, z důvodu snadno nepostřehnutelných side efektů a snadno přehlédnutelného probublávání přes vrstvy API, čímž ale neříkám, že je nerozumné je používat.
Domnívám se, že podstatnější než typ paradigma zpracování chybových stavů je SW craftsmanship (odtud souvislost přes oslí můstek, kterého jsem se z lenosti dopustil).
Jinými slovy nástroj (kladivo - výjimky - předávání chyb v návratových hodnotách funkcí atd.) je méně důležitý než způsob(y), jakým s nástrojem pracujeme
(jsou místa s omezenými zdroji, kde se můžeme k tomuto tématu hodně naučit).
BTW když budeme důslední, i Golang má "výjimky" runtime, které lze zachytávat s pomocí defer mechanizmu
(ale má to svá omezení a špecifiká ;-).
> máme mnoho daleko komplexnějších systémů, u kterých prostě nedokážeme předem promyslet všechny stavy. A tam jsou výjimky velice užitečné, protože zajišťují to, že výjimečný stav není ignorován.
U výjimek se nezřídka stává, že je ignorováno rozlišení výjimečných stavů, což vede k jejich chybnému zpracování.
Když aplikační programátor chce ignorovat chyby, paradigma zpracování chyb mu v tom nezabrání, ani mu nepomůže chyby zpracovat lépe.
Z hlediska paradigmatu zpracování chyb je např. srovnatelné, pokud mám try catch os.exit nebo "univerzální" obalový handler ir err os.exit (takto je implementována významná část sw).
posunout k "výjimky nejsou jediné nezbytné a zázračné" paradigma.
S tím souhlasím.
U výjimek se nezřídka stává, že je ignorováno rozlišení výjimečných stavů, což vede k jejich chybnému zpracování.
To se samozřejmě může stát, každý nástroje je možné použít chybně. Ale rozdíl mezi volitelným čtením chyb z návratového kódu a výjimkami je ten, že když vývojář na ošetření zapomene, v prvním případě aplikace vesele pokračuje dál a páchá škody, zatímco v druhém případě výjimka probublává tak dlouho, dokud s ní někdo něco neudělá, nebo dokud nedorazí úplně nahoru, kde typicky způsobí ukončení zpracování, takže aplikace nepáchá škody. Ano, programátor může výjimku zachytit a zahodit, nebo jí zpracovat špatně, ale to už se musí aspoň trochu snažit. A programátoři mnohem méně často páchají škody záměrně, většinou prostě jen zapomenou. Proti zapomínání se navíc dá použít koncepce kontrolovaných výjimek, například její implementace v Javě se ale nesetkává moc s pochopením.
> programátoři ... většinou prostě jen zapomenou
Jak se mi v Go může stát, že zapomenu zpracovat chybu ?
Buďto ji zahazuji záměrně s pomocí _ (když nebude sedět počet návratových parametrů, tak mi Go vynadá) nebo ji do něčeho ukládám, řekněme třeba err a potom mi Go vynadá, když err zapomenu použít/zpracovat.
Go nikomu nevynadá, pokud err není nově deklarovaná, takže zpracování chyby pominout jde. Tady mimochodem býval v překladači bug jak Brno, error je sice rozhraní, ale pokud vrácená chyba byla instancí jiného typu než původní hodnota v err, program padal, protože se špatně aktualizovala dispatch tabulka.
Řekl bych, že je to trochu podobný případ, jako když v jazyce s kontrolovanými výjimkami jedna funkce vyhazuje kontrolovanou výjimku, programátor se rozhodne, že jí nebude řešit a nechá jí probublat dál – a pak zavolá jinou funkci, která vyhazuje stejný typ výjimky, ale tu už by ošetřit v daném místě měl. Rozdíl je v tom, že v případě výjimek se to neztratí, ale ta výjimka alespoň probublá výš. Ale samozřejmě to zase není binární rozdělení, že na ošetření chyb se buď zapomenout může nebo nemůže – opět je to škála, někde to jde snáze a někde hůře, a záleží i případ od případu.
@unicode
Souhlasím že bez znalosti konkrétního kódu je těžko se o tom bavit. Dodám, že záleží i na koncepci jazyka. Ovšem já nejsem ten kdo tu začal tvrdit, že vyjímky jsou špatně by default. A taky si nevzpomínám že by někdo tvrdil že jsou vyjímky silver bullet. Proč to musí být v IT pořád odezdi ke zdi: Když vyjímky, tak všude jinak jsou na prd a když ne, tak nikdy nikde ... ?
Pokud bych měl ale opravdu vznést nějaký obecný soud, tak jakmile se začne řešit aplikace kde je struktura používání tříd a volání funkcí hodně složitá do hloubky co se týče volání (např. komponenta která používá komponentu která používá několik příd které obsluhují několik tříd - ideálně ještě různých vendorů), tak tam začínají být vyjímky velkou výhodou. Ono totiž to tzv. probublání ušetří tunu kódu a je naprosto hned jasné co se tam děje.
AFAIK u každého manuálu k vyjímkám a u každého slušnějšího tutoriálu je napsané, že vyjímky neslouží křízení toku programu a nejsou náhradou za větvění.
Pokud je problém v tom, že je špatně používá část programátorů, tak asi není správný postup řešit to odstraněním vyjímek by default, nota bene ne proto, že nejsou silver bullet. Ostatně co je ... Když se někdo snaží, zprznit jde všechno ....
Moc nechápu ty co to brali doslova a nedokázali interpretovat toho smajlíka. Za mě je to např. tak, že v aplikaci (doména C++) mi výjimky nějak extrémně nevadí, ale ve sdílených knihovnách už ano. Druhá věc je, že místo toho, aby tady lidi psali argumenty o které se můžou opřít, tak tady opakujou dávno vyvrácené mýty a zrůrazňujou jak dlouho už programujou :)
Abych to rekapituloval. Celé to bylo o tom, že bez výjimek to dnes rozhodně jde a nové programovací jazyky je výslovně nepotřebují (viz Rust, Go), pokud jsou schopné poskytnout jiné prostředky pro error handling. Druhá věc je ta, že současný stav výjimek v C++ rozhodně není ideální (tak jak tu někteří tvrdí) a je to "the least portable feature". Např. embedded, emscripten, C interfaces / language bindings - zapomeňte na exceptions.
A např. jeden z nových návrhů, který chce řešit současnout nevyhovující situaci v C++ nazvaný "Zero-overhead deterministic exceptions: Throwing values".
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf
Nemám moc čas na žabomyší války, takže tímto bych to ukončil :)
Znám hlavně C++, Javu a Python používám velmi málo. V C++ jsou výjimky podle mě opravdu na naprosto výjimečné stavy, protože na první pohled nevím, jestli funkce něco takového vrací a jestli je to relativně normální stav. Dělat něco takového jakože výjimku odchytnu přes šest zanořených funkcí je podle mě spíš prasárna, ulehčí to práci, ale někdo může použít funkci na třetí úrovni zanoření jinde a zapomenout na to.
V ideálním světě aspoň existuje dokumentace ohledně toho jaké výjimky funkce vrací, ale stejně ji málokdo čte.
@pp
No ony totiž ty vyjímku jsou opravdu na vyjímečné stavy - je to takový v podstatě chytatelný exit. Paradigma je takové, že je to jako nouzová brzda, kterou ovšem můžeš vědomě odchytit a odbrzdit v momentě, kdy jsi schopný situaci zase dostat do normálu, resp. standartního běhu. Toho docílíš tak že nevěštíš co úrovně pod nebo nad mají či nemají dělat, co možná kdyby někdo, ale buď tě stav vyjímka zajímá a zpracuješ ho nebo to necháš letět (probublat) dál a pak třeba někdo kdo používá tvou knihovnu která nechá tuto vyjímku z jiné knihovny letět se rozhodne jestli ho zajímá nebo ji nechá letět dál, resp. výše ....
Nevím jak v C++, ale například v tom zlém a nanicovatém světě PHP je už v podstatě standard do anotací uvádět všechno co ta funkce může hodit, minimálně deklarace jména. Taky existuje určitý standart jak vyjímku pojmenovávat - asi nebudeš muset moc hledat v dokumentaci když v anotaci je throws InvalidArgumentException nebo throws ConnectionFailureException - řekl bych že to není nic nepředvídalného ani hrozného .... Třeba ve Wordpresu se ti vrátí "něco" nebo objekt Error - tam je fak super chceckovat jesti tam není nějaký který tě zajímá :-O
Heh, to jsou kecy.
Na tom ze: "lidi začali používat výjimky pro ne úplně výjimečné stavy" je spatneho konktretne co?
Co je to "ne úplně výjimečné stavy"?
Normalni lidi kolem me pisou program zkratka tak, ze implementuji algoritmus korektniho prubehu. a vyjimkama resi vsechny deviace od tohoto prubehu. Vcetne nexistujiciho souboru, ci spatneho loginu do DB.
Korektni prubeh je v try, zpracovani chyb v catch blocich. Netusim, co na tom ma byt masochistickeho.
A co se tyce blaboleni o Resut<> ci Optional<>, v cem je presne lepsi kontrola existence hodnoty v Optional<> lepsi, nez prosta C like kontrola chyboveho stavu hned po volani funkce?
A "Pokud se bavíme o nějakém zjednodušení control-flow při výskytu chyby" - tak zde prosim doporucuju zkratka implementovat vyjimky.
Tvoji reakci bych popsal asi takto:
When you have a hammer, you want everything to look like a nail.
A co se tyce blaboleni o Resut<> ci Optional<>, v cem je presne lepsi kontrola existence hodnoty v Optional<> lepsi?
Vždyť to je jen syntax. C/C++ nemá elegantní návrat dvou hodnot, tak se to řeší takto. Jazyk který to má to může řešit klidně i jinak.
Výjimky jsou výjimky ze standardního průběhu programu - nikoli pro výjimečné situace. Tedy člověk implementuje průběh, který očekává jako ideální, a ostatní ošetří pomocí výjimek. A zbytek - včetně těch neotevřených souborů, či cokoli jiného. Neuvěřitelně to zpřehledňuje program, pokud se to dělá dobře, a činí ho tisíckrát srozumitelnějším a tedy udržovatelnějším.
Dobře implementované výjimky navíc zrychlují program. Když se nepoužívají výjimky: Ony ty miliardy ifů ve standardní cestě po volání každého podprogramu také nejsou rychlostně zadarmo. Kromě toho je rozdíl, když funkce musí vracet 2 hodnoty namísto jedné, protože do jedné si strčí chybu - už jsou to další strojové instrukce navíc = další zpomalení.
Programovací jazyk bez výjimek je něco jako špatný vtip.
Tady je relevantní video o exception cost v C++:
https://www.youtube.com/watch?v=XVofgKH-uu4&feature=youtu.be&t=1h2m24s
Pokud má někdo něco co by ukazovalo opak, tak se rád podívám.
Zdá se, že si nepochopil o čem je ošetřování chybových stavů, a to včetně výjimek. Výjimky jsou o tom, že standardní cesta programu je rychlá, ošetřování výjimečného stavu je pomalé.
Dělat benchmarky rychlosti ošetřování chyb je skvělé, ale mám pro tebe jednu radu: Nejrychlejší ošetřování chyb je vůbec je neošetřovat - přesně tam míříš.
Lidi většinou zajímá, jak rychlý bude program, když nenastane chyba a problém. Když nastane chyba a problém (třeba výjimka), pak daleko zajímavější než rychlost je kvalita ošetření chyby - a tam výjimky excelují. Často se ta chyba dokonce někam loguje či otevírá dialogové okno se zprávou - a to už je rychlost úplně vepsí. Ale asi je to podle tebe chyba.
"Když nastane chyba a problém (třeba výjimka)"
A v tomhle je jádro sporu. Někteří diskutující hovoří o výjimce jako o chybě nebo problému. To bude váš případ a to bude i můj případ. Jenže pak jsou tu lidé, kteří výjimky považují za zcela běžný nástroj a používají ho i na věci, které nemají nic společného s chybou nebo problémem. Jejich programy jsou prolezlé výjimkami, protože oni nikdy netestují, zda soubor existuje, zda text je číslo apod. Oni to prostě ZKUSÍ a jedou dál. Jejich program neobsahuje kód "pokud existuje starší soubor, tak ho smaž". Jejich program obsahuje kód "smaž starší soubor a ignoruj výjimku FileNotFound".
Zde si vždy vzpomenu na jeden extrém, kde autor prostě procházel pole stylem "for(i = 0; true; i++)". Smyčku opouštěl tím, že to měl celé v TRY bloku a odchytával OutOfBounds exception. Je fakt, že pole má jen omezenou velikost, chyba nebo problém? Není to třebas samozřejmost? A co čtení souboru? Viděl jste, kolik lidí tam místo "while not eof" má prostě natvrdo čtení a chytá si výjimku "read beyond end of file"? Je snad skutečnost, že soubor má omezenou délku, chyba nebo problém? Nebo když testují, zda existuje záznam v tabulce, tak místo COUNT(*) tam dají prostě SELECT 1 INTO a odchytávají výjimku NO_DATA_FOUND. Některé zvrácenosti se už dostaly i do tutoriálů. Například že kontrola, zda řetězec obsahuje číslo, se provádí tak, že se v TRY prostě zkusí přetypovat.
PS: Pro chyby a problémy Go nástroj má. Viz Defer, Panic a Recover. Používá to právě na věci jako je čtení mimo rozsah pole. Můžete to použít také. Není to tak silné a pohodlné jako výjimky, ale možnost to je.
> Jenže pak jsou tu lidé, kteří výjimky považují za zcela běžný nástroj a používají ho i na věci, které nemají nic společného s chybou nebo problémem.
to je otázka konvence. Třeba používání vyjímek pro ukončení iterace.nebo pro vyskakování z rekurze je podle mě elegantnější než řešit speciální návratové hodnoty.
Rozdíl je v tom, jestli o takové situaci přemýšlejí jako o něčem, co může nastat. Vyhodit výjimku je jedna věc. Druhá věc je napsat veškerý nadřazený kód až po místo chycení tak, že s ní počítá. Dosáhnout aspoň základní "exception safety" (jak se to překládá?) není až taková sranda.
A vůbec tomu nepomáhá, že v kódu obvykle není poznat odkud to může a nemůže lítat. Výjimky (alespoň v obvyklé podobě) jsou neviditelné při běžném čtení. Musím se podívat na jednotlivé funkce abych věděl, jestli náhodou nehází. Ify jsou sice opruz, ale aspoň je hned vidět, kde to může selhat. A jak o tom při psaní autor uvažoval.
O výjimkách se říká, že se nedají ignorovat. Není to pravda. Mezi místy odkud vyletí a kde ji někdo chytí je spousta příležitostí pro její ignorování. Nebo spíš pro ignorování možnosti, že výjimečně může něco stát.
V tomhle se mi moc líbí nový návrh výjimek v C++. Pokud je nechytám, tak každý házející výraz musím označit pomocí "try". I při zběžném čtení bude vidět, že to může vyletět a že se to bude propagovat výš. Už se dá trochu líp přemýšlet o tom, jestli mi náhodou nějaká data nemůžou zůstat v nekonzistentním stavu.
Chovat se při programování jinak dle toho, zda si předtím prověřím, co tam může a nemůže lítat je dost krátkozraké. Co až tam někdo něco změní tak, že dřív to neházelo a dnes to hází? To ten volající kód přestane fungovat?
Dále - selhat může tolik věcí, že představa, že mám nějakou část zkontrolovanou je dost iluzorní. Selhat může třeba alokace paměti, což ve vyšších jazycích znamená, že to vylítne při spojení dvou stringů. To si opravdu prověřuješ, že se tam nikde nedějí takové věci?
Závěr - předpokládej, že to může vylítnout kdekoli a podle toho piš kód. Program jako celek musí být navržen tak, aby se s tím dobře vypořádal. Jako bonus dostaneš prostředí, ve kterém nemusíš řešit jednotlivě každý převod textu na číslo.
Alokace paměti tímhle způsobem takřka neselhává. Když dochází paměť, tak se dějou zajímavější věci. Na Windowsech se program obvykle uswapuje k smrti. Začne swapovat tak divoce, že vlastně prakticky zamrzne. Na Linuxu se to liší podle nastavení. Asi nejlepší je, když swapper náhodně vybere obětní proces a ten sejme. S overcommitem je taky sranda. Malloc alokuje virtuální adresový prostor bez fyzické paměti. Fyzické stránky se přidělují až při prvním přístupu. Takže to pak vypadá tak, že žádná výjimka nevyletí a program segfaultuje při přístupu do úspěšně alokované paměti. Řeknu na rovinu, že v posledních +-10 letech jsem bad_alloc nepotkal. Ale je možné, že některé jazyky tohle chování OS maskují a chovají se kultivovaněji.
> Závěr - předpokládej, že to může vylítnout kdekoli a podle toho piš kód.
Pokud to opravdu může vylítnout kdekoliv, tak se s tím nedá nic dělat. Leda tak doufat, že se to nestane a po chycení výjimky všechno zahodit a začít znova. Pro psaní exception-safe kódu je kritické mít místa, kde to vylítnout nemůže. Klasický obrat je vytvoření nových dat kde to může lítat + výměna původních dat kde to vylítnout nesmí. Pokud to může vyletět opravdu kdekoliv, pak se konzistence zaručit skoro nedá.
Ten úklid se musí dělat nejen po chycení výjimky. Ten úklid musí proběhnout po celé trase, kudy ta výjimka letí. Něco může uklidit garbage collector, ale třeba mutexy neodemkne. Nabízí se otázka, jestli i ten úklid může házet a co v takovém případě udělat. Tady se vedou vášnivé diskuze a shoda moc nepanuje.
A o co mi šlo je, že pokud může výjimka vyletět odkudkoliv, tak se to může stát zrovna ve chvíli, kdy nejsou splněné nějaké invarianty. Pokud se chci z chyby nějak zotavit, tak musím při chycení vědět, v jakém stavu se může objekt, odkud to vyletělo, nacházet. A pro to už je potřeba nějaký commit nebo rollback, který házet nemůže. Bez toho se nemůžu přesunout mezi validními stavy, ale můžu zůstat v nějakém polorozbořeném stavu, který ani nemusí jít korektně uklidit.
Minimálně nějaký swap/přiřazení a destrukce musí jít provést bez házení, jinak se nedá spolehnout ani na ten úklid.
@JSH
Chápu. Myslím že na to není přesná odpověď, protože to záleží na tom jaké jsou požadavky - minimálně na to jak se má SW, případně i HW, chovat navenek ... Jediné co se dá říct s jistotou je že musíš v kódu tak nebo onak ošetřit stavy všechny a s použitím vyjímek ošetřuješ jednak všechny normální průběhy - což ale po nefukčnosti jednoho celku může dále znamenat normální chod programu (třeba přechod na default config) - a druhak všechny errorové stavy.
Podle mě stavů a požadavků v projektu neubude ani nepřibude, jenom s použitím vyjímek je metodika trochu jiná. Např. když jsem nedávno dělal kus SW kde jsem chtěl aby celý běh proběhl tak nebo tak, případně skončil errorem a vypsal všechny vyjímky které posbíral po cestě, tak jsem Exceptions vůbec nepoužil. Až při volání tohoto kusu, protože pak už bylo potřeba vyexitovat s hláškou, kódem, a daty, zapsat všechny errory na výstup i do logu - tedy použiji vyjímku.
To je pak ale špatně vyhozená vyjímka. Ten catch, případně final, je tam proto aby se ošetřily ty stavy a vyjímka je takový lepší exit+notice, který se dá nějaké úrovni přerušit volajícím - tedy lepší variabilita. Že má jazyk vyjímky neznamená že musí letět vždy ...
A o tom celou dobu píši. Plho!
Že standardní cesta programu je rychlá jako raketa, pokud nenstane chyba. A že ošetřování výjimky je pomalé, velice pomalé. Což je přesně to co chceme - rychlý program, pokud vše jede jak má, a kvalitní ošetření chyba pokud se něco zadrhne.
Tady se nějak množí lidi, kteří neumí číst či co!
Výborně, takže se možná shodneme na tom, že za ošetření chyby jsme ochotni platit nějakým časem navíc, tedy v systémech, kde to jde (tudíž ne mission critical věci). Proč ale pořád píšete o nějakém otevírání souborů? To se skutečně dnes považuje za tak výjimečný stav, že se kvůli tomu musí tvořit objekt s výjimkou, používat RTTI, cold tables a kdoví co všechno jsem už zapomněl? Dokonce se vsadím, že mnoho lidí bude mít právě tu práci se soubory naprogramovanou blbě s použitím výjimek, než ti, co si poctivě projdou všemi možnými stavy.
U mission critical věcí sakra záleží daleko více na kvalitním ošetření chyb než na čemkoli jiném:
1) Představte si, že mission critical řízení atomové hlavice bude ošetřovat chyby rychle, ale zato nekvalitně. Takový unicode si vezme benchmark chyb, shlédne dvouhodinové video o rychlosti ošetřování chyb. Dále vezme nejrychlejší způsob, a ušetří při ošetření chyby tři nanosekundy. Následně zlikviduje Paříž chybným zaměřením cíle.
2) Nebo atomová elektrárna bude neočekávané stavy ošetřovat rychle - jen přitom vybouchne jako vedlejší efekt a zamoří půl Evropy jaderným spadem. Ale ušetřili jsme při ošetřování chyb jednu pikosekundu a to se vyplatí!
Mýty o tom, že se "výjimky mají používat jen pro výjimečné situace" tu šíří jiní - já tento mýtus a tuto hloupost nikdy nešířil. Tudíž ta otázka, zda je "otevírání souboru výjimečná situace" je směrem ke mně naprosto irelelvatní. Směřujete tuto otázku na špatnou osobu.
Výjimkou jsou pro jednoduše způsob, jak ošetřovat chyby a problémy - výjimečné i očekávatelné. Tudíž si neničím den ani mozek zcela zbytečnými filozofickými úvahami na téma co je a co není "výjimečná situace", protože tuto starost nechávám koňovi, který má větší hlavu. Já tyto věci k životu nepotřebuji.
> Na to že máte "30 let praxe" tu argumentujete jako malé dítě :)
"Promiňte, to je zajímavé, ale já když jdu s dětmi do lesa tak vždycky tleskám a dělám takové kšššc, abych případné zmije zaplašil."
"Tak to děláte zbytečně."
"Ale já to tak dělám už asi 20 let a věřte, že se mi to plně osvědčilo."
"Ano... to je úplně zbytečné."
U mission critical věcí se výjímky prakticky nepoužívají (viz třeba JSF C++).
Problém je v tom, že jak ta výjimka probublává nahoru, tak cestou toho může dost rozvrtat, nechat objekty v nekonzistentním stavu a podobně. A když není jasné, odkud všude může výjímka vyletět, tak se prakticky nedá napsat kód který nějaká výjímka z nižší úrovně nerozvrtá.
> Tudíž si neničím den ani mozek zcela zbytečnými filozofickými úvahami na téma co je a co není "výjimečná situace", protože tuto starost nechávám koňovi, který má větší hlavu. Já tyto věci k životu nepotřebuji.
A podle čeho se teda rozhodujete, zda danou věc obsloužíte mechanismem výjimek nebo "normálně"? Hodíte si kostkou?
Mimochodem, jako člověka, který se v průmyslové automatizaci pohybuje celý život, mě často baví laické představy o architektuře řídících systémů jaderných zařízení. Ale prozradím vám, že výjimky v tom smyslu, jaké je známe třeba v Javě, se tam rozhodně nepoužívají. Výjimky v hardwarovém smyslu ano, ale už jsme to tu spolu řešili - to není totéž. Rozlišování výjimka-přerušení zde má svůj smysl a to, co máte na mysli, je spíše hardwarové přerušení.
On celý ten embedded svět je trochu jiný a spousta těch vychytávek, jako objekty, výjimky apod. se tam ukazuje jako zbytečná a spíš nebezpečná, takže se volí raději podmnožiny možností nástrojů.
* A co se tyce blaboleni o Resut<> ci Optional<>, v cem je presne lepsi kontrola existence hodnoty v Optional<> lepsi, nez prosta C like kontrola chyboveho stavu hned po volani funkce?
Predpokladam, ze se specificky ptas na Result v Rustu (Option je v necem podobny pripad, ale vyuziti ma jinde). Vyhodou je, ze ta "uzitecna" navratova hodnota v pripade chyby neexistuje, neda se k ni nijak dostat a omylem ji nekde pouzivat. Pokud funkce vraci kod chyby a "uzitecnou" hodnotu, programator ma tu hodnotu k dispozici bez ohledu na to, jestli volana funkce indikuje chybu. Coz je spatne principialne a nebezpecne v praxi. Dava Ti to smysl?
A co se tyce blaboleni o Resut<> ci Optional<>, v cem je presne lepsi kontrola existence hodnoty v Optional<> lepsi, nez prosta C like kontrola chyboveho stavu hned po volani funkce?
Moderní IDE nebo kompilátor dělá (u jazyků, které mají null hodnoty) kontrolu flow dat a s pomocí anotací, návratových typů funkcí apod. se snaží odvodit, zda daný typ je nullable nebo not-null, a pokud je nullable a neuděláte kontrolu, vypíše vám varování. S Optional
je tahle analýza mnohem jednodušší, IDE ani kompilátor nemusí trasovat kód nijak daleko, prostě jen k deklaraci proměnné. Jakmile pak v kódu narazí na to, že voláte get()
bez kontroly, zda není Optional
prázdné, může vám vypsat důrazné varování, že je to asi špatně.
Ja ted predelaval jeden poctive napsany projekt z php4 na vyssi verzi a velmi se mi ulevilo, ze novejsi verze php pouzivaji vyjimky. Dost podstatne to zjednodusuje program. Protoze kdyz poctive osetrujete kazde volani funkce a predavate tuto informaci nadrazenym funkcim, zda nedoslo k chybe, tak 70 % programu se venuje jen tomuto zpusobu osetreni chyb.
Problém s vaším příkladem je, že jste zkopíroval protipříklad :-)
Korektní řešení je totiž:
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
V jazyce s výjimkami byste to musel korektně napsat nějak takto (příklad je v pseudojazyce):
func CopyFile(dstName, srcName string) int64 throws FileException {
src := os.Open(srcName)
try {
dst := os.Create(dstName)
try {
return io.Copy(dst, src)
} finally {
dst.Close()
}
} finally {
src.Close()
}
}
nebo
func CopyFile(dstName, srcName string) int64 throws FileException {
var src *os.File
var dst *os.File
try {
src = os.Open(srcName)
dst = os.Create(dstName)
return io.Copy(dst, src)
} finally {
if dst != nil {
dst.Close()
}
if src != nil {
src.Close()
}
}
}
Což bych se zdráhal označit za elegantnější řešení.
Samozřejmě lze nalézt příklady, kde budou výjimky výrazně elegantnější. Ale stejně tak lze najít příklady, kde to je opačně.
Tak to dopadá, když se programovací jazyk Go dělá jako nalepovák. Nejdříve jej udělají s nějakými základními věcmi a syntaxí, a pak - eventuálně někdy, možná... - až se k tomu autoři dostanou... - do Go nalepí další věci, jako jsou třeba generiky nebo výjimky (viz jejich FAQ).
Výsledkem bude nakonec nepoužitelný nalepovák, protože jazyk se má nejdříve navrhnout v základních rysech a pak implementovat. Až tam pár features do Go přidají, bude to nekonzistentní nalepovák ála Čapkova povídka když pejsek s kočičkou vařili dort.
Výjimky při šíření výjimečného stavu postupují nahoru po zásobníkových rámcích musejí uklízet lokální proměnné a rušit epilogy/prology funkcí. Je třeba při návrhu jazyku přemýšlet, jak to budete dělat, a co výjimky konkrétně v každém zásobníkovém rámci uklidí.
Například v C++ se budou automaticky volat destruktory objektů, tedy nějaké close() metody pořeší kompilátor při šíření výjimky, programátor se o to starat nemusí. Automaticky se dokonce i dealokuje paměť, pokud je použita pro pointery, které ještě nebyly nikam přiřazeny. Kód je pak velice přímočarý.
Mám spíše dojem, že Go je nešťatně navrhován. Autoři si myslí - a svůj omyl záhy pochopí - že featury lze snadno do programovacího jazyka evolučně přidávat. Není tomu tak, vznikají tak totálně nekonzistentní jazyky. Příkladem jak to dopadá můžete vidět v PHP.
Přesně tak, typický příklad nalepováku je C++. Také leccos nalepovali dodatečně - a leccos drhne. Odnesla to hlavně zbytečná složitost C++ jazyka.
Myslíte, že když jsem si mimo jiné pročetl FAQ přímo od autorů Go, a na základě toho si udělal názor - že jsem čerpal z neseriózního zdroje? Zkuste mi prosím doporučit serióznější zdroj než jsou autoři Go, abych nepoužíval podle vás špatné zdroje!
Go jako nekonzistentní nalepovák skončí, protože přesně takto si autoři představují výrobu a vývoj programovacího jazyka. V tomto stavu a množině vlastností autoři Go nechat nemůžou, takže budou muset časem vlastnosti přidávat, pokud má ten jazyk rozumně přežít.
Můžete mi říct, jak jste přišel na toto tvrzení? Pravdou je totiž přesný opak. Od verze 1.0 se totiž do jazyka nepřidala žádná nová konstrukce. Na úrovni jazyka jsou první a nejnovější verze zcela kompatibilní. Autoři se právě zdráhali přidat některé funkcionality, o kterých nebyli stoprocentně přesvědčeni, aby nevznikla potřeba něco v průběhu času měnit.
Rozhodně se nekoná žádné evoluční přidávání. Existují návrhy na podporu generik, ale ta budou případně zahrnuta do Go 2.0, což je označení milníku, který má obsahovat všechny změny jazyku.
Takže na wikipedii ve sloupci "Language changes" u změn verzí Go lžou?
https://en.wikipedia.org/wiki/Go_(programming_language)
Je to hrozné, jak se na wikipedii lže a kecá! A to má anglická wikipedii tolik editorů! Že to neopraví, lháři jedni a šiřitelé fake news o Go jazyce!
Mně hlavně připadá absurdní, že autoři Go byli frustrováni složitostí jazyků jako je C++ či Java, a přitom se vydávají zcela stejnou cestou, aby došli časem k témuž výsledku.
Na počátku v prvních verzích byly C++ i Java pěkné, jednoduché a nijak těžké ani komplexní jazyky. Ty dnešní obludy se z nich staly až časem, když se postupně přidávalo to a ono. U C++ i Javy to jde chápat, protože v době jejich vzniku nemohli předvídat vývoj, který nastane v programovacích jazycích.
Jediná cesta, jak udělat moderní jazyk bez složitostí je navrhnout ho od začátku se všemi koncepty, které tam dříve či později hodláte mít. Jinak jdete neomylnou cestou k molochům ála C++, Java či PHP.
Já už se těším, jak bude Go nalepovat třeba ta generika. To se najednou zjistí, co všechno v současné verzi Go se nedomyslelo a příliš neladí s generiky!
Výjimky v Go možná budou, možná nebudou přidána - to se uvidí. A zase bude problém, protože se na to nemyslelo od začátku!
Pěkný zástup tvrzení, pojďme se na ně trochu podívat ;-)
Prosím můžete upřesnit, kterou "první" verzi C++ (https://isocpp.org/std/status) považujete za "pěknou, jednoduchou a nijak těžkou ani komplexní" ?
Co z vlastností, které Rob Pike uvádí jako inspiraci z C++ projektů ke vzniku Go tato "první verze" C++ prosím neměla ?
Proč Vám počáteční referenční specifikace jazyka C++ přijde srovnatelná se stávající referenční specifikací jazyka Go (rozsah počáteční referenční specifikace C++ / rozsah aktuální referenční specifikace Go se má zhruba 10/1) ?
U kterých "moderních jazyků" se prosím podařil počáteční návrh se všemi koncepty (tedy kde dříve či později něco nepřibylo - aneb existuje alespoň jeden pozitivní příklad funkčnosti uvedené "knížecí rady") ?
> ... a mizerna standardni knihovna je momentalne nejvetsi bolest golangu ...
Které https://golang.org/pkg/ a v čem jsou prosím mizerné ?
Napriklad neumi Collections-Containers, neco jako tohle"
http://www.cplusplus.com/reference/stl/
Neumi ani takove zaklady jako je Set nebo OrderedMap, klidne by stacilo bez generik jenom drzet reference a vysledky pretypovavat, jako v Jawe 1.4.
Prakticky umi jenom array/slice a unordered map - konec srandy.
Libovolna manipulace se aspon trochu strukturovanymi daty je neskutecny pain-in-the-ass.
A co jsem si vsimnul, lidi to obcazej jak u blbejch na dvorku pres JSON.
> Neumi ani takove zaklady jako je Set nebo OrderedMap
Základy jsou pro mě typy, které umožňují srozumitelnou (případně elegantní) implementaci komplexnějších datových struktur. K tomu Go evidentně stačí array/slice a unordered map .. Důkazem budiž právě standardní knihovny (packages) Go a projekty v Go, kde s komplexními datovými strukturami pracují.
Základy mohou být ještě méně rozmáchnuté než u Go, např. seznam u Lispu či tabulka u Lua a oběma to stačí na JAKÉKOLIV komplexní datové struktury.
Podle mě jakákoliv sorted kolekce v základech jazyka vede spíše k nesprávnému užití (používám ji na něco, kde není třeba a zbytečně plýtvám zdroji) či neutěšenému designu (typ reprezentace sorted kolekce může být u stejného datového typu pro nějaký use case vhodný a pro řadu jiných zcela nevhodný).
Zařazování komplexních datových typů do základů jazyka vede k nepřehlednosti, naboptnalosti a zejména neortogonalitě jednotlivých vlastností jazyka (užití vlastností nejde zcela nezávisle kombinovat). Přijde mi, že nezařazování kontejnerů, vektorů, matic, tenzorů, ... do základů jazyka (pokud to není přímo domain specific jazyk jako třeba R) je přednost (nikoli vada) designu jazyka.
> Libovolna manipulace se aspon trochu strukturovanymi daty je neskutecny pain-in-the-ass
Pro programátora formovaného "objektovými" programovacími jazyky určitě, stejně jako pro něho bude tortura vzdát se přiřazování do proměnných a programovat funkcionálně - použití Lisp maker (princip kód a data jsou jedno a totéž) pro něj bude za úrovní nepochopitelné magie.
Jakmile si rozpustíme bariéry, co jsme si dobrovolně postavili a zkusíme pracovat v paradigma slupkových API s vrstvenými Go interfaces ala streamy, můžeme řadu bolestí převést na eleganci. Jestli to chceme je jiný typ problému ;-)
> Mna naozaj fascinuje ako ludia, co robia v Go doslova adoruju jeho nedostatky a nedorobky ako vyhodu
A: Preferuji cihly, vyhovuje mi jejich jednoduchost, proto jsem si je vybral.
B: Ale cihlám schází takové základní věci jako armovací dráty, úchyty na jeřáb, to panely normálně mají.
A: Já jsem spokojený s cihlami, dá se s nimi postavit to samé co z panelů a jsou flexibilnější.
C: Fascinuje mě, jak lidi co dělají s cihlami doslova adorují jejich nedostatky a nedodělky jako výhodu.
Ja bych se na tvem miste neomezoval na rigidni GO.
Co vsecko muzes udelat assemblerem!
Nejses omezenej nesmyslnyma konvencema int/int64/float apod.
Udelas si vsecko sam.
Treba, muj priklad z praxe z te pekelne slozite Jawy, uz jsem ho tu jednou daval.
Mam tabulku ciselniku cca 300 polozek (pair id-name), potrebuju vystavit jako combobox na webu, nebo jako REST.
V pekelne slozite Jawe jsou to tyto 2 radky kodu:
List<TtTypes> ttTypesList = this.sQLRepository.findTtTypesAll();
LinkedHashMap ttTypesCombo = ttTypesList.stream().collect(Collectors.toMap(TtTypes::getName, TtTypes::getId));
TtTypes je entity bean, jednoduchy bean obsahujici vsechny sloupce tabulky jako atributy + par JPA anotaci
Prvni prikaz rekne JPA provideru (v mem pripade Hibernate) aby nacet kompletni obcah tabulky a vratil je ve forme ordered listu.
Druhy command trasformuje ordered list na ordered map, ktery primo davam jako vstup Primefaces komponente pokud chci webovy combobox, nebo oanotuju, pokud porebuju REST.
V GO nic jako java LinkedHashMap nebo C++ std::map neexistuje, pouze unordered map. A dokonce je ta go mapa zamerne randomizovana, zrejme ze stejnych "logickych" duvodu, proc vyjimky ne-e.
D: Třeba potřebuješ do baráku okno, na to je přímo speciální panel z fabriky, hele tady tahle jedna položka z 1600 typů panelů co můžeš použít, cihly nic jako okna nemají.
A: Já na to používám předpřipravené stavební bloky, přivezou mi to taky sestavené, nepotřebuji to z fabriky na cihly (tam se soustředí na cihly a ty jsou pak fakt super), vozí mi to z fabriky na okna, víš já okna třeba do garáže nebo psí boudy nepotřebuji a představ si necpu je ani do sloupku na přivedení sítí.
D: Nebo když potřebuješ tu cihlu přepůlit, vždycky prdne na jiným místě.
A: Víš to je schválně, aby se na to lidi nespoléhali, protože když by řezy byly symetrické, stavěly by se z toho menší zdi a pak ty zdi nejdou dobře spojovat a napojovat.
D: Já bych se na tvém místě neomezoval na cihly, co všechno můžeš udělat s hlínou! Nejsi omezen nějakým debilním rozměrem, uděláš si všechno sám.
A: Asi by mě to nebavilo.
https://www.acara.cz/predpripraveny-vnitrni-roh-kerdi-schluter-e22560.htm
http://www.blokki.cz/
Library např. https://github.com/spf13/cobra
Jaké pojmenování prosím navrhujete, aby podle Vás dávalo smysl ?
Chápu význam slova "připravený", nechápu význam slova "předpřipravený". Co to má být? Jaký význam v té zkomolenině má ta nadbytečná předpona "před-"? Podobně úchylný mi připadá "podtácek" (on je taky nějaký nadtácek?), "20tý" nebo dokonce "40cet".
"Připravit" znamená nachystat k něčemu - tedy před něčím. "Předpřipravit" už tedy nedává smysl. To slovo, které hledáte, je prostě "připravit". Připadá vám málo sexy? To je snad nějaká úchylka... "Hmotnost" ani "váha" se nepozdává, ale líbí se mi "gramáž" - někde jsem to zaslechl, sice nevím, co to znamená, tak mrsk s tím do nabídky. Hmm.. "ukrást".. to zní hospodsky, "odcizit" - to zní slušněji, ale "zcizit" - to se mi líbí úplně nejvíc, to jsem už někde zaslechl, to bude asi vono. Hoodinky nebo holínky, hlavně že se použije nějaký hezký termit.
Díky za osvětu. Lingvisti ze mě nebudou mít radost, jsem opice co používá slova, která nějakým mechanizmem uvízla a bojuji s nedostatečnostmi jazyka - ať jde o moji slovní zásobu či vyjadřovací možnosti (čímž neříkám, že vím jak lépe na komunikaci). Často jsou to docela zkomoleniny, protože nezřídka hledám ekvivalenty z angličtiny, což asi byl i tento případ https://www.merriam-webster.com/dictionary/preprepared
Akademický slovník současné češtiny nějak zrovna nejel nebo co, tak jsem to tam jen tak mrsknul ;-)
Za nesrozumitelnost anglikanismů a dalších nesmyslů se omlouvám, naštěstí se najdou laskaví čtenáři, kteří vstřícně pomohou. Dokonce vědí jak mi to připadá sexy, že mám úchylky, jak se mi to pozdává či líbí, že nevím co to znamená nebo jak mi to zní a chci to mít hlavně hezké. Nad takovou moudrostí se skláním, já bych si tohle všechno vůbec neuvědomil!
"prepripraveny" je myslim docela jasne, wocogo.
kdyz je neco "pripravene", tak to proste vezmu jak je a vrazim, kam patri.
ale kdyz to je jeste treba mirne doladit, ne vsechno, jenom male detaily, aby to zapadlo, tak je to "prepripravene"
neco jako polotovar, ci sablona - taky polotovary nejime jenom tak, ale je jeste DOupravujeme, a sablony taky jeste DOvyplnujeme ...
podobne je to i s vyrazem "pos.rany" (vyznam asi neni treba vysvetlovat) a s vyrazem "predpos.rany" :)
Kiwi: To „tedy před něčím“ jste si tam doplnil vy. „Gramáž“ je normální termín označující hmotnost jednoho metru čtverečního dané věci, je to tedy něco jiného, než hmotnost či váha. Odcizit a zcizit jsou právní termíny, zcizit znamená „změnit majitele“, odcizit pak je „ukrást“. Nadtácek nemáme, ale máme tácek, která znamená něco jiného, než podtácek. Mohl byste takto rozebrat i váš text a ptát se, proč píšete „nachystat“, když máme slovo „přichystat“, proč „nadbytečná“, když existuje slovo „zbytečná“.
Vy se na něco připravujete až po "tom"? Tomu se u nás říká s křížkem po funuse. Připravuje se vždy v očekávání něčeho budoucího, tedy časově před něčím. Proto je předpona "před-" naprosto zbytečná, protože sémantika něčeho předcházejícího je nedílnou součástí slova "připravit".
Na to jsem právě poukazoval. "Gramáž masa je před tepelnou úpravou." "Pachatel zcizil kolo." Proč ti lidi prostě nepoužili slova, která znají, a vymýšlejí si novotvary, jimiž se nevědomky trefují do již zavedených pojmů, které ale znamenají něco úplně jiného?
Další podobné patvary jako "předpřipravit" jsou "nejaktuálnější", "nejoptimálnější" apod. To je jak "lepšejší". Prosím, když takto žvatlají předškolní dítka, může to být i roztomilé.
> Mohl byste takto rozebrat i váš text a ptát se, proč píšete „nachystat“, když máme slovo „přichystat“, proč „nadbytečná“, když existuje slovo „zbytečná“.
Vidím, že vám naprosto chybí cit pro jazyk a jeho logiku a poukazujete na něco úplně jiného. "Chystat" je imperfektivní kořen a k němu se pojící předpony mají perfektivizující význam, jinak jsou synonymické. "Předpřichystat" už by byl opět nesmysl. U kořene "pravit" ale mají předpony navíc i sémantický význam: při-pravit, na-pravit, vy-pravit, po-pravit, o-pravit, s-pravit, z-pravit... Předřazování dalších předpon je v češtině možné, ale musí dále modifikovat smysl: roz-pro-střít, za-po-šít, při-po-strčit, ne-před-po-s.aný
E: Za to si mohou autoři cihel sami. Když omezili cihly jen na stěny, oblouky, pilíře, plochy. Když by hned od začátku udělali cihly jako pořádné panely, tak už se dají cihly dávno svařovat stejně jako panely a není potřeba malta se všemi omezeními které má.
A: Borci, všimli jste si, že popisuji proč mi vyhovují cihly a nikomu je nenutím ani neimplikuji že musí vyhovovat někomu dalšímu ? Jsem rád za pestrost světa a speciálně za panely, je z nich spousta staveb, nebýt frustrace autorů cihel z panelů nevznikly by cihly, hromadě lidí panely vyhovují. Užijme si jak stavění z cihel, tak z panelů a podívejme se, kam nás to zavede. Občas sáhnu po panelu a necítím se z toho provinile ;-) Proč máte takovou neodolatelnou potřebu radit ostatním co je pro ně dobré/nejlepší (přesvědčení že víte co je "správná" cesta pro ostatní) ?
X: Jenže panely jsou rychlejší.
X: A taky mají odvodňovací kanály, to cihly nemají.
X: Panely
X: Panely
X: Panely
...
Výjimky v Go nikdy nebudou, Rob se vyjádřil opakovaně. Oni na ně nezapomněli, oni je tam nedali schválně (stejně jako hromadu jiných věcí). Stejně tak nebude hodně dlouho ani Go 2 - vylepšení ošetření chyb a možná i generika budou součástí 1.x. Jsem za to rád, pokud někdo chce N-tou variaci Javy, C++, C# nebo Rustu tak ať si vybere jiný jazyk, možnost volby tu je. Díkybohu Go zůstane čisté, to je totiž ta nejdůležitější vlastnost co má. A autoři to moc dobře ví.
Tenhle jazyk opravdu má budoucnost, pokud k tomu budou takto přistupovat i nadále.
Čerstvá přednáška od Roba na toto téma: https://www.youtube.com/watch?v=RIvL2ONhFBI