Hacker News new | ask | show | jobs
by hpbd 2759 days ago
I don't understand. I have a C background. What is wrong with that?
2 comments

In many languages invented since c that have errors as values, you can use something akin to a specialized monad to sequence things which may fail together.

For example, in rust you could use:

    let res1 = w.Write(...)?;
    let res2 = w.Write(res1)?;
In haskell, you can use do notation or monad binding to do a similar thing.

Of course C doesn't have a good type system that allows this sort of thing; it was created before such type systems were well known.

I would expect any modern language to at least recognize that there are good ways to sequence and compose types.

Probably the repetition of

if err != nil {}

You get used to that pretty quickly in Go, but it still looks messy to a lot of people.

And so it's clear to others, this probably the worst possible way for a language to go about implementing error handling (maybe aside from just not having any mechanism outright and terminating).

But alas, those are the choices that the Go language made.

Is it really though? I've tried out Exceptions in most languages and Go's error handling stuck out to me as the first one that is clear what it does, which of course is the mantra of the language.
Exceptions are a strawman.

Compare it to another modern language such as rust. Go does not have a stdlib mechanism for converting error types into each other (akin to rust's Into), it doesn't have the idea of mapping values together (akin to rust's carrier operator which is basically like monad do syntax), it doesn't have a way to create a list of errors by default (akin to 'cause' in rust), it doesn't have a way to generate concrete error types for your functions (like the 'failures' or 'error-chain' libraries in rust, which can't be written in go due to a lack of macros and generics and sum types).

It doesn't have a way to match on all possible concrete error values (akin to 'match' in rust or other sum-type things) or to do thing slike '.and_then' or '.map_err' or so on.

Go's error handling is downright insulting in a language that wasn't built at the same time as c.

The alternative is just as bad, a multi block try and catch mess that is in Java!
No, the alternative here would be to just let the write()'s throw and let upstream handle them. You don't try/catch to catch an error just to re-throw it for the same reason you don't try/catch every single line of your program.

Exceptions are one reason other languages don't need this "if err throw err" code, without making a comment on if either is superior.

Yeah, but an error error is not really an exception. Often in Go, errors are used to mark different states, such as EOF which are expected and you can deal with locally and have more control whenever you want to return or not, for example, you can test the error in the same if condition and decide whenever to keep going - usually you do. Error handling code is more local rather than all over the place, plus no need to declare more classes for specific exceptions.
> Often in Go, errors are used to mark different states, such as EOF which are expected

Then it's not an error, and Go has once again forced people into writing something semantically confusing and/or incorrect because it lacks basic abstractions.

Actually, any type can be an error, just as long as it impliments the Error interface. Go is more about interfaces - if some type impliments some interface, then that's what it is.