3 ms·
That just means you have written a lot of go. I truthfully don't notice lifetimes or the borrow checker most of the time when I write rust. I actually think th
by thayne 4y ago
That just means you have written a lot of go. I truthfully don't notice lifetimes or the borrow checker most of the time when I write rust.
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.
- derangedHorse 4y agoI don't see how that's a specific problem of the Go programming language though. Rust still has option types and the cases where an Option could be None still need to be handled. Maybe the big difference is the compiler forcing the handling of this case but it seems like a small thing for experienced programmers. 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.
- thayne 4y ago> Rust still has option types and the cases where an Option could be None still need to be handled 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.
- tptacek 4y ago`map` and its cousins make Rust error handling code easier to write. It doesn't make error handling easier to follow. And Rust introduces the problem of "thicket of different error types". And that's before we get to the sync/async boundary. There's a lot not to like about both Rust and Go's error handling. People need to stop pretending that either language has this answered perfectly. 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.
- thayne 4y agoHaving used exceptions, like in java and python, checking error return values like in go and to some extent c, and using ADTs to represent error conditions like in rust, haskell, and scala (scala has exceptions too, but it's arguably more idiomatic to use Option, Try, etc.), primarily in application code, I by far prefer using ADTs. IMO it is a good balance between explicitness and verbosity. And ensuring you handle errors is built in to the type system.
- 3a2d29 4y agoI feel like the err != nil issue combines with GO using initialization to 0 values to be annoying. If you forget err != nil, well your value does actually have a value and you would think your result was 0.