8 ms·
I guess then I have to ask, why would try() make that worse? Because I can't stand Golang error handling. It's repetitive, it's error prone, and other language
by KirinDave 7y ago
I guess then I have to ask, why would try() make that worse?
Because I can't stand Golang error handling. It's repetitive, it's error prone, and other language features interact with it so that when you make a mistake it can be as hard as a double free to track down where the erroneous default value was introduced.
On the other hand, using Rust, Ocaml, F# or Haskell I understand how my code composed and I can be confident I can just use an error handling strategy. The only complexities appear, as with everyone else, when we have asynchronous code.
So I don't mean to disagree with your feelings, but they're sure not mine and they're part of why I don't use Golang. I was excited about try() because it at least addressed the most tedious part.
- Thaxll 7y agoHow returning (val, err) is error prone? It's verbose but it's clear and definitely not error prone. I spent so much time working with Java and useless giant stacktraces or with Python and people not knowing what to do inside a try / except.
- _hardwaregeek 7y agoIt's error prone in that you aren't forced to handle the error. In languages such as Rust or Haskell, you have a Result type which can either be an Ok(val) or an Err(err). In order to "unwrap" a Result, you have to check the error case. Basically there's a compile time guarantee that errors are handled.
- Thaxll 7y agoI'm not a Rust expert but afaik Rust doesn't enforce error checking since you explicitly need to unwrap(). It's very possible to panic because you forgot to check something. It's similar in Go since you can't compile with unused variable so you need to explicitly discard the error with _. Ex: result, _ := func() This is for multi-value returns, for single value you can even omit the _ https://golang.org/doc/effective_go.html#blank https://golang.org/doc/effective_go.html#blank
- jpittis 7y agoHaving unwrap() in your Rust code is like littering your code base with panic(). It’s not appropriate to use in most production code, but is convenient in prototypes, examples and tests. Your example re Go errors is incorrect. The go compiler allows you to ignore errors in returns without any compiler error. For example err := doThingThatErrs() and doThingThatErrs() are both valid Go code.
- Thaxll 7y agoMy example is correct I explained all of that, multi values -> need to omit, single value can ignore everything.
- jpittis 7y agoYup. I misspoke. We’re both right.
- edflsafoiewq 7y agoThere's nothing wrong with unwrap. It's just an assert. Even a[i] is just shorthand for a.get(i).unwrap(). Asserts are definitely appropriate in production code, just not for handling run-time errors.
- jbverschoor 7y agoThen how is this better than anything else? Except for syntactical sugar for: Try Return [Bla(), null] Catch err Return [null, err] End I do like this syntax better, bc the different scopes cause a lot of nesting
- djur 7y agoRepetition and verbosity in a language can create errors in at least two ways. First, by the developer losing track of which error case is which (and/or copy-pasting error-handling logic) and doing the wrong thing in the error case. Second, by reviewers who have become trained to notice and gloss over error-handling boilerplate not noticing when there's something wrong with a particular case. Concise languages can be more challenging to read because you have to understand more about each symbol/word in the language. But verbose languages can be more challenging to comprehend because there's a lot of symbols which don't signify anything.
- kartickv 7y agoInteresting perspective. Are you expressing an opinion about "explicit is better than implicit", or is your point on a different axis? I suppose concise / implicit is fine when the thing that's being hidden can't go wrong, like in: [i * 2 for i in 1...10] The loop counter increment logic can't possibly go wrong, so it's fine to not think about it. Regarding error-handling, don't you want to think about? If you're calling a() followed by b(), what should you do if a() fails? In some cases, b() shouldn't be called, but in others, it should, like deleting a temp file. And if you have to think about it, it's better to be explicit?
- wolco 7y agoyou have 'catch' to handle those cases. Try and catch are easy to notice when scanning the codebase.
- djur 7y agoMy preferences are that error handling is expressed in and enforced by the type system (Haskell's Maybe/Either, Rust's Result), that common error handling tasks be supported by the standard library and by specialized syntax when necessary (Haskell's many Monad/Applicative tools, Rust's "?" operator), and that if a developer neglects or chooses not to handle an error that the most likely outcome is that it bubbles up to some kind of top-level crash handler that terminates the current task and produces whatever useful diagnostics are possible (exceptions in many languages). To put it more simply: yes, the developer should have to think about what they do in the case of an error. And then the amount of work they do -- and the code produced, and thus the work reviewers have to do -- should be proportionate to how unusual the necessary error handling is. When I see explicit error handling, that signals to me "hey, this is an important case that we need to handle in a particular way".
- kerng 7y agoCopy/paste is very error prone. Golang code is full of it. I see lots of similarities between Visual Basic and Golang, incl. the passionate communities behind the languages.
- pjmlp 7y agoWith the difference that Visual Basic is an academic language full of needless features from Go's community point of view.
- mikeschinkel 7y agoVisual Basic is hardly academic; they is a tremendous amount of line-of-business code that has been written in VB over the past 25 years. But yeah, Go dev do not see VB's features as being "features."
- pjmlp 7y agoThe point was that many of VB.NET features are what many in the community attack as being academic and not worthy of being adopted by Go.
- mikeschinkel 7y agoGiven that I have worked with VB long before .NET even existed, I have a broader view of it than just the more recent criticisms. VB's biggest problem IMO is that it tried to compete with C# instead of maintaining its original raison d'être which was to be a highly productive tool that required very little programming skill to be able to start building real solutions for business use. But I digress...
- mikeschinkel 7y agoCurious, do you see other communities that are not passionate about their languages?
- NateDad 7y agoTry makes it worse because it is so easy to miss when reading the code. Because it encourages nesting function calls, which is harder for a human to parse than separate statements across lines. Because it means you can exit the current function from the middle of a line of code, and what runs before or doesn't run before is based on order of operations rather than requiring the exit to be a statement on its own line whose order cannot be misunderstood. Because it discourages giving more information with an error, so instead of "failed to open config file: EOF", you just get the EOF. Go's error handling isn't any more error prone that writing if statements for all the rest of your code. if err != nil is no different than if age < 18. Either one is a branch in the code. I can literally count on one hand the number of times in 6 years of full time go development that I've seen people miss writing the if err != nil. Being explicit is good. Spreading out the logic is good. Cramming a lot of logic into one line is bad.... and that's the sole purpose of try. Maybe there's another way to make error handling better in Go. I'm not averse to looking into that. But try wasn't it. You're talking about writing if err != nil being tedious, but what about matching Results from Rust, isn't that tedious? What about writing proper catch blocks in java or C++ or python, isn't that tedious? It's all just logic.
- wybiral 7y ago> Because it encourages nesting function calls, which is harder for a human to parse than separate statements across lines. I absolutely agree. Beyond the human parsing aspect it also makes commit changes easier to reason about and review. I want functionality to be limited per-line and view the ability to combine a lot of functionality into one line as a liability more than a benefit. Go's error handling isn't carefree or hands-off, but that's because error handling is serious. Especially in network code and cryptography.
- gigatexal 7y agoI thought it could lead to doing method chaining for a fluent like API which I find cleaner than how things work now.
- 7y ago
- grey-area 7y agoI don't particularly mind try, but would prefer that they addressed the boilerplate which is actually annoying to type out (the convention is to return zero values and the error (annotated or not depending on what other functions have already annotated it)): if err != nil { return ...,...,err } If there were a shortcut for returning that error + zero values without interfering with the function call which produces the error (as try does), I'd prefer it. Something more like check(err). We'll see what they come up with next though to try to address this. I can't say I've ever had problems tracking down an error, not sure what you mean about default values - surely if you check the error you won't use the values returned. My only problem with go error handling is the verbosity, which isn't a huge deal.