With try, Go might have been a language I'd have enjoyed using. It's a shame. Right now, I see Go as being anti-abstraction and anti-cleverness, and I'd rather not work on codebases in which the language of choice is designed to deter creativity and encourage monotony. Heavy use of Go is a big negative when I evaluate potential projects to work on.
Anti-cleverness is what makes Go great. Go code is simple, and it is easy to read/understand. It's a feature of the language
Declined Proposal: A built-in Go error check function, “try”
301–310 of 425 posts
Re: Declined Proposal: A built-in Go error check function, “try”
#302It's rather disappointing that Go has managed to bungle error handling so badly in a language only a handful of years old.
Personally I find go error handling okay but that’s because I exclusively use panic().
Re: Declined Proposal: A built-in Go error check function, “try”
#303Earlier quoted context omitted.
Try 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…
The difference with catch blocks in Java, C++ or Python is that you only need to write them when you actually have something g meaningful to do. If you only need to propagate the error or cleanup resources then propagate the error, then all you would write is... Nothing. And cleanup+propagation is by far the most common error handling strategy. In Java and Python exceptions even add context for you automatically to h…
Using Rust, which makes errors explicit like Go, has been eye-opening to me. My programs never crash because I've handled every error condition. No effort on my part. No tests needed.
Re: Declined Proposal: A built-in Go error check function, “try”
#304Earlier quoted context omitted.
The difference with catch blocks in Java, C++ or Python is that you only need to write them when you actually have something g meaningful to do. If you only need to propagate the error or cleanup resources then propagate the error, then all you would write is... Nothing. And cleanup+propagation is by far the most common error handling strategy. In Java and Python exceptions even add context for you automatically to h…
One foundational principle of Go is that the sad path is at least as important, and maybe more important, than the happy path. The best Go programmers I know write the sad path of their programs first, and then backfill the happy-path logic. So: > you only need to write [error checking] when you actually have something meaningful to do. Although it's the subject of a lot of ridicule, `if err != nil { return err }` is…
err = doThing()
if err! = nil {
return errors.New("Error doing thing", err)
}
This doesn't add any useful information for whoever is reading the code, it's just boilerplate that you learn to skip while reviewing, while hopefully not missing any important thing that does happen on the error path.As for 'programming with the error', I would like to see an actual use case for constantly doing this, and why exceptions would prevent that pattern. The only one I can remember is something highlighted as a 'good practice' by Rob himself: write everything you want to a bufio.Writer, without checking the error messages, and then calling Flush and only then checking if maybe something failed. If this is good, safe, sad-path-first, errors-are-values style... then my taste in programming is obviously bad. Obviously, the same could be achieved with exceptions.
Re: Declined Proposal: A built-in Go error check function, “try”
#305Earlier quoted context omitted.
Literally the first non-trivial code I wrote in go (running a bunch of goroutines to download a ton of files from a website in parallel)... I knew exactly where and how things could fail and where things were failing just by looking at the code. Coming from C++ and C# and Python, there was no comparison. I had never been so confident in the code I'd written, even though I was a newbie at Go and a veteran of the other…
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 conf…
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.
Re: Declined Proposal: A built-in Go error check function, “try”
#306Earlier quoted context omitted.
> 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 caref…
I thought it could lead to doing method chaining for a fluent like API which I find cleaner than how things work now.
Re: Declined Proposal: A built-in Go error check function, “try”
#307Earlier quoted context omitted.
Go error handing _is_ fundamentally fine the way it is. That is, the verbosity would certainly benefit from some sugar, but the semantics -- errors managed by separate expressions/blocks immediately adjacent to the error-generating code -- is fundamental to the language, and one of its great strengths.
I repeatedly tell people that Go takes twice as long to write and half as long to debug. Unless you write perfect code on the first try, the trade off is probably worth it.
I often get the feeling that Go users are implicitly comparing it to languages like Python or JavaScript.
I've watched a client try to debug a Go codebase they had. It was sad. Their web server just returned 500 Internal Error and they tried to track down why from logs, but by the time the error had made it back up to the serving loop most information about where it came from had been lost. I suggested they attach a debugger to a server to see what's happening, they said debuggers don't work that great in Go and so people don't use them much.
If they'd been using exceptions they'd have a stack trace and could have pinpointed the source of the fault in seconds.
Re: Declined Proposal: A built-in Go error check function, “try”
#308Earlier quoted context omitted.
Seems identical to Java: try { var val1 = happy_path1(val0); var val2 = happy_path2(val0, val1); var val3 = happy_path3(some_val); function_might_crash_let_it_crash!(some_val); return happy_result(); } catch (NotFoundError e) { handle_notfound_error(); } catch (PermissionError e) { report_permission_error(); } catch (Exception e) { throw new Exception("don't worry this process is supervised, let it crash!"); }
If you're rethrowing the exception, what happens in the VM if that exception is not caught? IIRC, the VM exits, so, it's not at all identical. There are potentially severe nonlocal effects and you're already coding defensively by putting a catch/rethrow.
Re: Declined Proposal: A built-in Go error check function, “try”
#309Earlier quoted context omitted.
One foundational principle of Go is that the sad path is at least as important, and maybe more important, than the happy path. The best Go programmers I know write the sad path of their programs first, and then backfill the happy-path logic. So: > you only need to write [error checking] when you actually have something meaningful to do. Although it's the subject of a lot of ridicule, `if err != nil { return err }` is…
> `if err != nil { return err }` is actually bad Go code, and not often written by good Go programmers. Like the people who wrote the Go stdlib? Because that's filled with those - just look at the net/* packages.
Re: Declined Proposal: A built-in Go error check function, “try”
#310This thread is rife with "Go should have Try because I want Try" that also seem to be made by developers that do not write Go. It seems confusing to me that voices generally involved from Go are so demanding of its maintainers. Curious, are there full-time (or at least Primary) Go developers that are upset by the lack of Try?