I actually think that, ironically, the if err problem with go is worse for reading code than writing code. If you are used to the pattern it's not that difficult to add the `if err != nil` after a fallible function call, and as is mentioned elsewhere, linters can help catch if you miss it. However, if you are trying to figure out what a function is doing, it can be very difficult to follow the flow, when 3/4 of the code is
if err != null {
return err
}
especially if you don't have a lot of experience reading go code. And that 3/4 is not an exaggeration. I have had to read functions where literally every line of normal logic is followed by those three lines to propagate the error from the other function. A function that would otherwise fit on a single screen now takes up over three screens worth of scrolling.Rust's default paradigm for memory management seems more significant of a language feature in my opinion and is what I can imagine most people don't like. A lot of the programs I write don't fall into the class of problems Rust is trying to prevent which makes the restrictions it enforces bothersome for me.
And rust has the `?` operator, as well as combinators like `map`, `and_then`, `unwrap_or_else`, etc. which IMO make the flow much easier to follow than say `if option.is_none() { return None }`.
> Rust's default paradigm for memory management seems more significant of a language feature in my opinion and is what I can imagine most people don't like
I never said it wasn't. My point is that if you use a language enough you get used to things that are difficult for people less experienced with that language.
People complain about Go's wordy error handling, but systems programming is error programming. The places where Go's error handling is most annoying is in application code, where you'd ordinarily EAFP instead of LBYL. But that's also the code Rust is least convenient for.
Go vs. Rust is truly the dumbest programming language slapfight in the entire industry.
If you forget err != nil, well your value does actually have a value and you would think your result was 0.
> God I get tired of the generics criticism with Go. I truthfully don't even notice it when I write Go, I don't understand why folks get so bent out of shape over it.
Over ten years later, Go gets generics.
Every Go project I've worked on has used this linter. I think it should be builtin, but it's very easy to incorporate.
As someone who is adding this to a Go project with hundreds of unchecked errors, I disagree.
Anecdotally this is the same argument many C++ devs make in regards to Rust safety guarantees. The difference is just...different.
I also don't use much Go because it lacks good algebraic data type support, honestly can't imagine going back to a language that doesn't have them as I like to define all my business logic in types and then build the actual application from there. Go simply doesn't have that capability.
The language maintainers don't want to add it: https://github.com/golang/go/issues/19412
I'm not sure how they could be, given that Rust checks exhaustively and Go doesn't. If one programmer messes up, then that's it, an unhandled exception might occur in the future. I would rather rely on the computer telling me when it should be handled over humans.
I actually like Go over Rust, but really, really wish the language provided some more ergonomics and fixed several of its terrible gotchas. (the for loop issue for example)
Also wish Go gets RAII some day.
I don’t think that’s any better in Rust though.
let x = match foo() {
Ok(value) -> value,
Err(e) -> return Err(e),
} let x = match foo() {
Ok(value) -> value,
Err(e) -> return Err(e.into()),
}
Which can automatically convert one error type into another when the appropriate From and/or Into impls exist.https://github.com/rust-lang/rust/blob/4e0d0d757e2f1b61ec809...