5 ms·
With five years of Go experience at work (plus some casual Rust in my spare time), you learn to just skip over the `if err != nil` lines. It's not really a big
by majewsky 6y ago
With five years of Go experience at work (plus some casual Rust in my spare time), you learn to just skip over the `if err != nil` lines. It's not really a big deal.
It's like how people get overwhelmed when they read Rust code and they come across lifetime annotations for the first time. The unusual stuff sticks out and makes you trip up if you're not used to it. Once you are, it blurs into the background.
- stouset 6y agoHow can you skip over the `if err != nil` lines!? That's where the work is being done per canonical golang. Every line is if res, err := someDifferentWork(x, y, z); err != nil { return nil, err.fmt("look, ma! I'm a human exception handler") } Yes, Rust has lifetime annotations. Those are almost always only on function definitions, and consist of a small part of the overall definition. With golang, the above nonsense is repeated at least 2/3ds of every function body in practice. And the actual logic is embedded inside of it, over and over and over, with minor differences between each occurrence. `if err != nil {` is practically golang's newline separator. Look, I get that as you spend more time with the language you get better at mentally ignoring this. But a) comparing noise that's virtually 50% of most golang code in the wild to noise that's maybe 2% of most Rust code in the wild is frankly ridiculous. And b) the fact that you eventually got used to it doesn't make it any less of a readability disaster.
- aboodman 6y agoRight but the skipping over is part of the problem. If you want to know your code works you want to treat the error handling as carefully as the happy path. You can’t just skip over it. I’ve found so many bugs in Go that come down to shadowed err variables or forgetting to check an err on one case of 7. Haven’t you? This comes directly from the mental habit of filtering out the error handling. In well written software error handling is a majority of the paths through the code. But they are all very similar. So it’s a natural programmer inclination to both (a) want to handle them all explicitly, and (b) want to abstract away the similarities so it’s easier to see correctness. Languages with exception optimize for b and ignore a. Go optimizes for a and ignores b. But languages like Rust show that it’s possible to actually do both well. That’s what people are complaining about when they lament Go’s approach to errors.