3 ms·
On the other hand, exceptions are implicit control flow, which means you have to assume every single expression may throw an exception. So if you don't take ext
by jjnoakes 11y ago
On the other hand, exceptions are implicit control flow, which means you have to assume every single expression may throw an exception. So if you don't take extreme care to write strong exception safe code, subtle bugs will exist and are extremely hard to find.
Explicit control flow is more verbose, but it is also easy to spot when the control flow passes over something important by mistake. And as pointed out elsewhere, forgetting to check a return value is a solved problem via static analysis.
- aikah 11y ago> On the other hand, exceptions are implicit control flow Go doesn't force you to deal with errors either. I see plenty of code ignoring them with retval , _ := MightYieldAnError(); And some languages that have exceptions actually force the client code to handle them, like Java AFAIK . Finally, Go "explicit control flow" didn't have to be verbose like it is, that's a design choice its authors made. Go is primitive in the sense that it uses C style code patterns , like the famous : retval = MightYieldAnError( &outError); Edit: I forgot to mention the panic/recover which ultimately means Go designers implemented some form of exceptions. That basically voids the usefulness of Go error system, and an admission that it's broken.
- jjnoakes 11y ago> Go doesn't force you to deal with errors either. > And some languages that have exceptions actually force the client code to handle them, like Java AFAIK. But this misses the point. Any error which you have to explicitly ignore is fine, because then you were aware of it at some point and explicitly ignored it, and anyone reading the code can plainly see you explicitly ignoring them. And errors which can only happen at specific points (like function return values) are also ok, because then you only have to consider error handling and cleanup at those points. But if you have neither of the above - if you have the situation where errors can spontaneously result from any evaluation of any expression with no explicit notation required - then you have a poor situation indeed.
- iofj 11y agoGo has both error codes, and exceptions (panic/recover). Basic errors implicitly panic, such as null pointer exceptions, arithmetic errors, ... So in Go you have the worst of both worlds. Constant error handling code everywhere, AND you have to treat every single expression as if it may suddenly throw panics. Oh and to make matters even worse, Go has typed nil, which is not equal to untyped nil. So you cannot correctly check interfaces against nil, the most common cause of panics in my experience. // t is some kind of interface if (t == nil) { // t is untyped nil } else { // t is non-nil OR a typed nil } I'm not even sure what the correct fix is. Should every interface come with a isValid() method to check if it's usable ?
- TazeTSchnitzel 11y agoSwift has a nice middle-ground here. Functions which can throw must be marked as such, and if you call a throwing function, you must use the `try` keyword. You don't actually have to handle the error there (you can let it propagate, or choose to let the program crash), but you can if you want. This means there's no implicit control flow. You can always see where a function might throw, or know that a function will never throw. It also means, performance-wise, the implementation is much more efficient than C++-style stack unwinding. I've not used this in practice, because I've not tried Swift, but I think it's a good approach. https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html https://developer.apple.com/library/prerelease/ios/documenta...