5 ms·
Exceptions are a mistake, plain and simple. They should have never been added to the language. They break the notion of programming as a sequence of events.
by snarfy 9y ago
Exceptions are a mistake, plain and simple. They should have never been added to the language. They break the notion of programming as a sequence of events. With exceptions, now you have two sequences, the happy path and the 'wherever the hell the exception is caught' path. No matter how you slice it, exceptions are still a goto under the covers. If they are truly exceptional, you might as well call exit() too.
Go got this right. If there is an error, return it to the caller. The error can be a function, and the caller can call it when they want. This returns programming to a single sequence of events.
- krylon 9y agoWell, strictly speaking, Go has panic() which is very similar to exceptions. But it also has a culture that strongly discourages using it unless things go very wrong.
- dullgiulio 9y agoNo, think of panic() as unhandled Segmentation Fault (and other Go specific unrecoverable errors). You can handle Segmentation Fault, but you need to know what you are doing. In Go it's the same.
- quotemstr 9y agoPanic is _semantically_ the same as throw. That Go culture treats panic like evil voodoo doesn't change how the language construct works.
- PopsiclePete 9y agoNobody in Go culture treats it as "evil voodoo" that I'm aware of. There are clear guide-lines. User passes in a path to a file that doesn't exist and you attempt to open it? Return an error. That's not "exceptional" or "programmer error" - it's just normal "shit happens". You have an array-like structure with 10 elements and your function that modifies it gets passed in index 13? That's probably a bug or programmer error, not "user" error - so panic. Go documentation is very clear on the difference between the two, actually. I've never been confused.
- jcelerier 9y agoBut panic is recoverable in go, with "recover()". That's literally the same mechanism than exceptions with a different syntax and keywords.
- deleted 9y ago[deleted]
- krylon 9y agoStrictly speaking, a) you can catch a segfault, too, by installing a signal handler, and b) recover() is not quite the same, because with "real" exceptions, you can state in a catch clause what types of exceptions you handle, and the compiler/runtime will do the right thing, where in Go, you call recover() and look at the return value to see if there is something you can do about it. And if not, I do not think you can even "re-throw" the panic further up the stack. (I think the panic()/recover() mechanism is intentionally crude in order to discourage people from over- or abusing it.)
- pjmlp 9y ago> a) you can catch a segfault, too, by installing a signal handler, My POSIX knowledge is a bit out of date, but if I remember correctly what actually happens is not guaranteed to work across all UNIXes.
- jhasse 9y agoGood luck getting a fully C++14 compatible compiler with exceptions working on all UNIXes.
- XorNot 9y agoExcept Go has panics and they turn up quite a lot looking exception-like. Go with panics moved to regular error returns doesn't seem like it would lose anything.
- m_mueller 9y agoMaybe panic is just a better name so people don‘t get the idea to use it for control flow in slightly less than normal situations? (i.e. ValueError, StopIteration in python).
- laneb 9y agoNothing about names like StopIteration and AttributeError indicate to me that I should use them for control flow. Python just instructs me to use them that way...
- m_mueller 9y agoMy point is, that part of python is IMO a bit ugly. Not due to naming, but because these are exceptions. A type system with good use of optionals across the standard lib is certainly more elegant than ValueError.
- quotemstr 9y ago> They break the notion of programming as a sequence of events. It's never been that way. What's a page fault? > No matter how you slice it, exceptions are still a goto under the covers. "break" is also a goto. What's your point? > If they are truly exceptional, you might as well call exit() too. That's completely unacceptable for robust software. Programs can recover from almost all errors and make forward progress, usually via staging some kind of rollback. Tearing down a whole process in response to error is a ridiculous extreme that works only in a few narrow domains. > Exceptions are a mistake, plain and simple. Is that why almost every language ends up adopting them in some way? Even languages that start out vehemently anti-exception, like Go and Rust, end up with the full try-and-catch exception toolkit. That's because, despite protestations, exceptions are extremely useful.
- deleted 9y ago[deleted]
- steveklabnik 9y ago> Even languages that start out vehemently anti-exception, like Go and Rust, end up with the full try-and-catch exception toolkit. Rust (and as far as I know, Go) have pretty much remained the exact same with regards to their implementations here. Go uses panic/recover a bit more liberally than Rust uses panic/catch_panic; using panic for control flow is not idiomatic, and so is not done. Since you can turn them into an abort, it's not something you can rely on when writing a library, and so I'm not aware of any significant libraries that do so. You couldn't even catch panics for a long time, and the possibility was mostly added to prevent UB with regards to extern functions.
- quotemstr 9y agoI find it amusing and sad that the Rust ecosystem, via this "panics as abort" feature, replicated one of the worst parts of the C++ ecosystem: -fno-exceptions, which, in C++, turns throws into aborts. In both language environments, the availability of a compiler option that breaks a language feature doesn't erase the existence of that language feature.
- mehrdadn 9y ago> They break the notion of programming as a sequence of events What about coroutines...?
- krylon 9y agoSwitching between coroutines is explicit, i.e. it will not catch you by surprise.
- stonemetal 9y agoThrowing an exception is explicit as well.
- Too 9y agoWhat's the reasonable alternative to exceptions? Checking return status or errno after every single function call and then manually propagating it upwards? (optional is a bit better but also falls into this category) Programmers are way too lazy for this and it usually ends up as either a redundant assert() crashing the whole application or just logging a error and continue with broken state. Exceptions is following the "let it crash" philosophy from erlang, instead of broken recovery code scattered all over your code. (Crash doesn't necessarily mean a linux process in this context, more of a high level) This is a very powerful concept that allows you to think about the bigger picture such as if _anything_ unexpected happens inside this transaction, return a error to the user and continue processing the next request from the next user. Error handling should be done by layers, not by grunt work. There are situations where I agree you might want to know how a certain function can fail, here I think javas checked exceptions strike a good balance between control vs verbosity as you just have to add a throws-clause if you don't want to handle a specific error at that point in the code.
- Ace17 9y ago> No matter how you slice it, exceptions are still a goto under the covers. This is a poor argument; the same could be said for almost all control flow statements: if/else, while, for, break, continue, (early)return ... they're all implemented using "goto under the covers". Moreover, lots of C programs use goto to do their error handling! Seeing "throw" statements as gotos misses the point: you can't really create spaghetti control flow using "throw" statements. Instead, you can see them as "return on steroids". It's true that "try-catch" makes it hard to know where your code is gonna "jump" ; but that's the point : as the "thrower", you don't have to know, and you don't /want/ to know. Think about the standard libraries for Java, C#, Python, D ... they don't have this luxury. If when using "throw", you're wondering "where's the catch", then you /probably/ have a design issue.
- smitherfield 9y agoAgreed. Minor quibble: >This is a poor argument; the same could be said for almost all control flow statements: if/else It's technically possible to implement if/else (and loop conditions) with unconditional jumps and offsets, but for reasonable instruction sets (that support conditional jumps) they won't be "goto under the covers."