Hacker News new | past | comments | ask | show | jobs | submit login

I haven't programmed in Go, but from what I understand, Go's explicit error handling isn't enforced by the type system, as you can leave off an `if err { ... }` check and everything still compiles. I think adding a generic result/error type (like the Result type in Rust or the Either type in Haskell) would be a pretty useful feature, as currently the error handling sits in kind of a weird place between forced handling and traditional exceptions.

I have no idea why you are being downvoted.

In Rust, this was handled the right way. The Result type forces you to at least actively dispose of the error.

In Go, it's just way too easy to leave an error unhandled.

> The Result type forces you to at least actively dispose of the error.

Sort of: by default, an unused value of the `Result` type produces a compiler warning. Like all warnings in Rust, this category of warnings can be promoted to a hard error for all users with a single line of code. And unlike other languages where compiler warnings are uniformly ignored, there is a strong culture in Rust of making sure that code compiles warning-free (largely due to the fact that the compiler is rather selective about what to issue warnings about, to help avoid useless false positives and warning spew (there is a separate project, called "clippy", for issuing more extensive warnings)).

I think you're thinking of Result<(), E>, whereas they're thinking of Result<T, E>, that is, you only get that warning if you don't care about the Ok value of the Result. If you need the value, you also need to deal with the error in some fashion.

This seems like a no-op to me. My stack of code tools always warns me of unhandled errors (insert argument about maybe the compiler should be doing it I guess?) but I've never understood how a Result type provides any real benefit over the usual error-tuple Go uses.

In both cases I have to either write a handler immediately after the call, or I'm going to fail and toss it back up to whoever called me.

Errors-should-be-values has always seemed like a bizarre statement to me. Like, fine, but they're still errors - their core feature will be that I stop what I want to do and handle them. And in that regard I much prefer exceptions (at least Python style exceptions) because most of the time I just want to throw the relevant context information up to some level of code which knows enough to make a decision on handling them. The thing I really want is an easy way to know all the ways something can fail, and what information I'm likely to get from that, so I can figure out how I want to handle them.

> In both cases I have to either write a handler immediaitely after the call, or I'm going to fail and toss it back up to whoever called me.

The main difference as I see it is that in Rust, you can't get the success value if there's an error, so you're forced by the compiler to handle any error if there is one. With tuples, you're free to just look at one element regardless of the value of the other.

In order to maintain compatibility with other interfaces, they have to return error in several places. Take bytes.Buffer, which return errors even when they are impossible. Same with http.Cookie(). It promises it will only ever be http.ErrNoCookie, but that isn't going to make static analysis tools happy.

Go's errors are really nice (if a bit repetitive) in my opinion. Type signatures enforce that you accept and acknowledge an error returned from an invocation, but leave it up to you to handle, pass along, or silently swallow.

So... Just like checked exceptions in Java?

Yes, it's somewhat similar in that the compiler checks if you have handled or chosen not to handle an error. You're not allowed to ignore it (through omission).

yeah but better because you don't break the world if you add a new exception to a public method.

Declaring that every method throws Exception doesn't break the world any more than every Go function returning an argument of type error. You're intentionally saying pretty much anything could go wrong and nobody can plan ways to recover.

Does that mean it now throws an error if you use the common punt like `foo, _ := …` and never check `_`?

No, because using `foo, _` you're explicitly saying that you don't care about the error.

No, but that's what I mean as intentionally ignoring.

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact