Live data from Hacker News

Declined Proposal: A built-in Go error check function, “try”

github.com

381–390 of 425 posts

Re: Declined Proposal: A built-in Go error check function, “try”

#381
post #257

Earlier quoted context omitted.

Interesting 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 cal…

My 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…

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.

Great comment. I would add how unusual _and critical_.

One of the things I love about Python is that while I know errors can occur on practically every statement written, I only have to add error handling for likely / expected / critical errors. Any unlikely errors that occur, even in production, will show a detailed stack trace (lots of context), making them easy to fix.

In my experience, things work as expected 98% of the time. For some software, like a pacemaker, checking the execution of every single line of code and even having redundant error checking is not overkill. For other software, like the backup software I work on, having one customer out of 1000 get a weird error is something I'd rather deal with as a support ticket rather than having to anticipate it while writing code.

Of course error handling is important, but requiring 3 lines of error handling for every 1 line of actual code has kept me from investigating Go to replace Python for HashBackup. I'd love to get the performance increase, but not for a 4x expansion of LOC.

Re: Declined Proposal: A built-in Go error check function, “try”

#382

Earlier quoted context omitted.

Aligned incentives? Making a “simple” operation as hard to write as it will be on the machine.

While not objectively a bad thing, that's at the crux of the problem many have with Go: it sets the bar very, very low for getting in your way instead of trusting you to be even slightly competent. Knowing basic data structures is engineering 101,and any engineer who'd (eg) blindly use std::find on a vector or "in" on a list in performance-critical code without understanding it isn't someone who should be committing…

> While not objectively a bad thing, that's at the crux of the problem many have with Go: it sets the bar very, very low for getting in your way instead of trusting you to be even slightly competent.

And there's nothing wrong with that, that's exactly Go's target audience.

Re: Declined Proposal: A built-in Go error check function, “try”

#383
post #33

This hits at something fundamental about Go, which is what I like the most about it... It's a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you're forced to carry them up the chain. Do I particularly like managing errors that way? No, but I do think that it improves the transparency and qual…

> And things like the lack of abstractions and generics are what create a community that's less reliant on dependencies. "A little copying is better than a little dependency" and you can see it in stark contrast to something like the JS community with its require('left-pad') NPM ecosystem.

"A little copying", "less reliant on dependencies"... do you even vendor bro

Re: Declined Proposal: A built-in Go error check function, “try”

#384
post #294
post #218

Earlier quoted context omitted.

> Curious, are there full-time (or at least Primary) Go developers that are upset by the lack of Try? I use golang at an employer. error handling in golang is verbose, error prone, distracting, and difficult to make sense of when there is actually an error (composing). I've seen on several occasions now errors being mishandled (either dropped by accident, or by overwriting already existing error variables in the same…

It's interesting that as a full time Go developer myself, my experience has been very different about the points you have mentioned. I personally think verbosity is good. For one, lack of verbosity catches my attention. If I am reviewing code that looks like some part of it is ignoring the error, I would try to find a reason about that error check exclusion. This also prevents errors being dropped by accident. About…

> This also prevents errors being dropped by accident.

Instead of designing a language that prevents errors from being dropped by accident, hire a bunch of literal gophers to search your codebase for inverbosity. Good plan will work 10/10 times.

Re: Declined Proposal: A built-in Go error check function, “try”

#385
post #33

This hits at something fundamental about Go, which is what I like the most about it... It's a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you're forced to carry them up the chain. Do I particularly like managing errors that way? No, but I do think that it improves the transparency and qual…

I agree. Handling errors is difficult and that is what it is. Many times errors can be handled properly in the function and "if" helps you think about it. Programmers shouldn't be lazy to handle errors, just forwarding them to the caller. That way it may end up like Java, where many functions throw something but lots of programmers don't care so programs simply crash with a long, confusing, unhandled exception stacktrace. How many ppl handle I/O errors in Python for example? Since I started using Go, my software is much more stable.

Re: Declined Proposal: A built-in Go error check function, “try”

#386

Earlier quoted context omitted.

Both are bad.

What's the alternative?

Good exception-based code shouldn't be littered catch blocks; you only need to catch in places where you can reasonably recover. No matter how complex the application, there are typically only a few places you can meaningfully recover from a real exceptional or unexpected error situation.

Checked Exceptions in Java, for example, force you to litter your code with catch blocks and error handling code that doesn't actually recover from the error. It transforms it. It propagates it. Languages like Go with explicit error handling do the same thing. I don't think that's bad in all situations but often it comes down to what one thinks is an unexpected error for a given project.

Re: Declined Proposal: A built-in Go error check function, “try”

#387
post #33

This hits at something fundamental about Go, which is what I like the most about it... It's a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you're forced to carry them up the chain. Do I particularly like managing errors that way? No, but I do think that it improves the transparency and qual…

> Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects. So long as we can all agree that it feels super bad, I guess this is fine. But it does sort of mean that Golang approaches the Java world back with checked exceptions where principle trumped ergonomics. That lead to a world where folks felt "forced" to use Java, and that's a sti…

I think it is unfair to label Go with "bad ergonomics."

It might be fair to say the ergonomics are suboptimal for the code _writer_, but I would say they are much closer to optimal for the code _reader_.

Re: Declined Proposal: A built-in Go error check function, “try”

#388
post #311

Earlier 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…

Writing Go professionally for 4 years already and being a Go fanboy since 2009: while endorsing many benefits of "if err" blocks, I do very much have the following issues with them (in no specific order): - It's hard to spot outliers. This leads to occasional bugs that tend to get easily overlooked in code review. Also, it makes code reading harder when an "if err" block is subtly different. The most common case here…

Just curious. Do you have a vision for how Go could change to improve your issues? (One of the key problems is nobody could agree on a better approach...)

Also, what editor/IDE do you use? The reason I ask is because of this: https://youtrack.jetbrains.com/issue/GO-7747

Re: Declined Proposal: A built-in Go error check function, “try”

#389

Earlier 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…

The fact that you need to add context to errors usually exacerbates the problem and makes it even harder to read the code. You often end up with 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 happ…

I would argue that if you are using boilerplate annotations, you are doing it wrong. If you really do not need to add context, don't add context. But in my code I find that I want to add context about 90% of the time.

But then I am super zealous about making sure my error messages understandable without the need to track down other information. For example, I want to know that (something like) "the config file needs group read permissions" not "file cannot be opened." But maybe others value ease of programming more than I do and are less concerned about error UX than I am?

Re: Declined Proposal: A built-in Go error check function, “try”

#390
post #313

Earlier quoted context omitted.

First, the signature for `errors.New` is `New(text string) error`. It won't take more parameters than that. So I guess you mean `fmt.Errorf`. If above is true, then how about: err := renderTemplate() if err! = nil { return fmt.Errorf("Error rendering template: %s", err) } The end error could then be something for example: Error rendering template: Compiler has failed: Cannot load template: File /tmp/test.tpl was not…

Oops, I forgot if errors.New takes the 'cause' as well. Regarding you example: the code itself still contains redundant information for someone reading it. True, the error ends up being nicer, though I would argue that the user would have been better served with a simple 'failed to load template file: /tmp/test.tpl', no need to show the pseudo call stack (so, only the fictional template loader should have been wrappi…

The full call stack is available in Go but it is up to the developer if they want to include it or not which they can do by creating a custom error type and implementing that to be part of their type. And having the choice seems like a benefit to me.
Post reply on HN