← Back to context

Comment by sapiogram

1 day ago

What are you talking about, only Rust actually forces you to handle errors. Go functions merely return a tuple with an error along with the result, with a convention that you must checktror a non-nil error before using the result.

Rust bakes this into the type system, a function can truly return a result or an error.

In practice you use Go with a linter, so this is not a problem in practice. I have never seen a missed error.

The problem is painstakingly and manually having to build the stack trace, and then unwrapping it few layers above if you ever need to check what error it was.

> with a convention that you must checktror a non-nil error before using the result.

So, you handle the error in the end, or forcefully and intentionally ignore it. Again, if the code goes boom, it's on the developer, not on Go.

> Rust bakes this into the type system, a function can truly return a result or an error.

Error being a variable or baked into the type system doesn't change the practical result. You must handle the error or purposefully ignore it.

> only Rust actually forces you to handle errors.

When you have two programming languages which makes you handle the error, the word only becomes a little invalid.

Semantics doesn't change the result. You have to acknowledge and act on the error either way.

  • > So, you handle the error in the end, or forcefully and intentionally ignore it. Again, if the code goes boom, it's on the developer, not on Go.

    Except Go doesn’t actually require you to handle the error. You can forget to handle the error, or forget to do a nil check. And Go won’t tell you until it crashes and explodes at runtime.

    Technically the user’s fault, but good systems protect the users from their own mistakes.

    • I agree with you that it would have been nice with Result and option types in Go.

      But as someone else pointed out, unhandled errors are very rare in practice in Go because every Go project tends to use static code analysis tools that catches this. When people talking about things blowing up during runtime I can’t help but think that they can’t be serious Go users.

      On every build I generally run vet, lint (revive), staticcheck, gosec and test. And that’s the “light” build that doesn’t run leak analysis, fuzzing, race testing, benchmark regression and integration tests in addition. The light build is still faster than the Rust compiler. I haven’t compared the heavier build.

      When people pretend the absence of features is a huge problem, I tend to think that these are people who either aren’t regular Go users or perhaps they are more interested in debating languages than writing code.

      Let’s not pretend this is something it isn’t.

      2 replies →

    • It's not hard to ignore an error in Rust, IME?

      Especially as someone who's read a lot of code written by newcomers to Rust.

    • Here's an example file: https://files.bayindirh.io/misc/error_example.go

      I have commented inside the code, but to recap here:

          - If you don't declare err variable, the code won't compile.
          - If you don't use err variable, the code won't compile again.
      

      So, you need to both declare and use the err variable to be able to compile the code. So you can't forget. Your code will not compile.

      The only way to "forget" is to declare err as "_", which I call IDGAF placeholder, and this is a deliberate choice to ignore that variable. So you willingly and knowingly ignore the error variable.

      Otherwise Go won't give you Go ahead.

      Seriously, try to compile the example I have given. It's fresh, so hold with mittens.

      5 replies →

  • > if the code goes boom, it's on the developer

    This is the same argument C (and Zig!) people have for manual memory management. You can avoid memory problems by being a good developer.

.unwrap().

I am skeptical about Go's error handling, but there are cases where it is desirable to return both a result and also an error, like returning what can be returned while warning users about any errors. That can be modeled in Rust and other languages as well, though it is the default for Go.