4 ms·
> But it results in still less cumbersome code, since you only need scoping for the error handling portions.) There isn't a meaningful difference in cumbersome
by pcwalton 7y ago
> But it results in still less cumbersome code, since you only need scoping for the error handling portions.)
There isn't a meaningful difference in cumbersomeness between having two try-catch blocks and two if-err blocks. There is a meaningful difference in cumbersomeness between what Go has today and "try foo(try bar())". Which is why it's so unfortunate that the community killed the try proposal.
> But forgetting that, because passing errors down in Go is explicit, it is actually customary to use error wrapping to add context as an error is propagated,
People say this, but in practice any code search reveals that "if err != nil { return err }" is everywhere. I believe that many Go projects aspire to annotate all errors, but much fewer actually do.
Ironically, the nice thing about exceptions, as well as Rust error chaining crates, is that they do this automatically, so in practice programs written in languages with those features tend to have better error diagnostics than Go programs do. Computers are better at doing things consistently than humans are.
> It is a simpler language than Java. You get most of the benefits of checked exceptions without all of the calories from exceptions.
Go is a more complex language than Java is overall, because of all the special cases the language adds to magic types like maps and errors that are just part of the library in Java.
- weberc2 7y agoI like your points about diagnostics. I definitely feel this—it seems like one of Go’s weakest points. That said, Go is still one of the best tools available for building software today.
- wybiral 7y ago> any code search reveals that "if err != nil { return err }" is everywhere Code searches in languages with exceptions tend to wrap the tryblocks around massive portions of code instead of the individual function calls to the point that you have a top level doing: try: ...program here... except: print('¯\_(ツ)_/¯')
- KirinDave 7y ago... I could do this with Golang too, couldn't I?
- wybiral 7y agoOn the opposite end of the spectrum, yes, as they pointed out you can just return all of the err's up the stack. I wasn't saying that Go's approach solves this, just that it's not a problem unique to Go. And in the case of Go it's painfully obvious that you're ignoring all of those errors whereas in other languages you can't always tell, visually, that they're being ignored because of the magic of exceptions.
- tsimionescu 7y agoBut that is exactly how error handling usually works, especially if cleanup is handled separately - you just need to propagate the errors, usually all the way up to the user, who is the only one who can take a meaningful decision. Almost all actual error handling in code is either error translation and re-throw, resource cleanup, or automatic retries (sometimes you retry the same request, sometimes you try a fallback option, but it's still the same idea). The user however may be able to check and actually fix their internet connection, they may fix the typo they did in the config file, they may call support to see what's happening to the database etc. - your program can't do any of these things. That's why exceptions work so well in most languages, especially GC languages where you have dramatically fewer resources to cleanup: they bubble up automatically towards the initial caller, which is often the user. Threading messes with this, but if you use the more modern async style (async/await in most languages) you get proper exception propagation even then.
- mikeschinkel 7y ago> That's why exceptions work so well in most languages But there are many people including some well-known and highly-respect people who believe that exception handling in fact does not actually work well: - https://www.joelonsoftware.com/2003/10/13/13/ https://www.joelonsoftware.com/2003/10/13/13/ - https://blogs.msdn.microsoft.com/larryosterman/2004/09/10/structured-exception-handling-considered-harmful/ https://blogs.msdn.microsoft.com/larryosterman/2004/09/10/st... - https://www.atlassian.com/blog/archives/exceptions_are_bad https://www.atlassian.com/blog/archives/exceptions_are_bad - https://stackoverflow.com/a/1736320/102699 https://stackoverflow.com/a/1736320/102699 - http://xahlee.info/comp/why_i_hate_exceptions.html http://xahlee.info/comp/why_i_hate_exceptions.html - http://www.lighterra.com/papers/exceptionsharmful/ http://www.lighterra.com/papers/exceptionsharmful/ #justsaying
- jchw 7y ago>There isn't a meaningful difference in cumbersomeness between having two try-catch blocks and two if-err blocks. There is a meaningful difference in cumbersomeness between what Go has today and "try foo(try bar())". Which is why it's so unfortunate that the community killed the try proposal. Object thing1; try { thing1 = doStuff(); } catch(SameException e) { // handle error 1 } try { return doOtherStuff(thing1); } catch(SameException e) { // handle error 2 } vs thing1, err := doStuff() if err != nil { // Handle error } thing2, err := doOtherStuff(thing1) if err != nil { // Handle error } return thing2 Happy path is flat. Control flow is obvious and simple. I have not much more to add. >People say this, but in practice any code search reveals that "if err != nil { return err }" is everywhere. I believe that many Go projects aspire to annotate all errors, but much fewer actually do. https://github.com/search?l=Go&q=%22errors.Wrap%22&type=Code https://github.com/search?l=Go&q=%22errors.Wrap%22&type=Code >Ironically, the nice thing about exceptions, as well as Rust error chaining crates, is that they do this automatically, so in practice programs written in languages with those features tend to have better error diagnostics than Go programs do. Rust is a different ball game. Rust does not try to be simple. It comes at its own costs. (I like Rust too.) >Computers are better at doing things consistently than humans are. These empty platitudes come up frequently when debating language decisions online. But, it's so meaningless in so many dimensions. I mean, we could also 'use the computer' by adding C macros on top of Go and use them to reduce repetitiveness, but I don't think many people will applaud you for it. Simply applying computer code to solve a problem does not constitute good design. Go's proof is in the pudding. It's been extremely reliable for me in real world applications.
- wybiral 7y agoThe fact that it allows for more nesting on a single line is a bug, not a feature, IMO.
- erik_seaberg 7y agodoOtherStuff(doStuff()) is the happy path, but it's been hidden among lines of noise that do nothing more than return to the callers who know what to do. Generating this using cpp or m4 would suck, but it's still better than not generating it due to wasted effort (especially re-reading) and mistakes.
- sagichmal 7y ago> There isn't a meaningful difference in cumbersomeness between having two try-catch blocks and two if-err blocks As demonstrated by the sibling comment to mine, this is wrong. > In practice programs written in languages with [exceptions] tend to have better error diagnostics than Go programs. Anyone who's spent time on teams working in exception-oriented languages like C++ or Python knows this to be clearly false. > Go is a more complex language than Java is overall This is obviously wrong. One need look only at the GC landscape to disprove it. Zero for three. Rust Evangelism Strike Force, go home.
- pcwalton 7y agoI'm not saying you should use Rust! I'm saying that Go should add try.
- mikeschinkel 7y agoI was one of the many who argued strenuously that they not add try(). I spent an entire day writing up my reasons who I posted to the ticket on GitHub. Bottom line, try() had too many flaws — especially related to consistency with the rest of Go — to be an appropriate addition to the Go language. Adding try() to Go would be like adding a disco ball to the Sistine Chapel. Sure, disco balls have their place, but some places are just not appropriate for disco balls. Or as Yoda says: "Do or do not. There is no try." (Fortunately!)