4 ms·
Give me a break. As the neighbor comment points out, this is necessary if you're writing production-quality code -- either your checking exceptions or checking
by xyzzy_plugh 6y ago
Give me a break. As the neighbor comment points out, this is necessary if you're writing production-quality code -- either your checking exceptions or checking errors, it makes little difference.
I've been writing Go almost daily for 5 years and have never thought writing if err != nil is remotely a plague. It's an opportunity to handle the situation gracefully, annotate the error or log with details and propagate or swallow. Each invocation becomes deliberate, routine, and meaningful.
If you're just trying to hack together a tire fire, then sure, maybe this is painful, but also maybe consider why you find this to be painful? What do you value, and if it's not what Go provides, why on earth are you using it?
- fulafel 6y agoMost production code is application code that is just good enough to work in the one setting where it's deployed.
- stouset 6y agoI write production-quality code in Rust, and the vast majority of my error handling consists of the character `?`. The mess of thousands of lines of `if err` and the lack of any language feature to actually deal with tuple returns as first class citizens was a mistake, full stop. It makes it significantly more difficult to actually read go code, since the actual logic is hidden amongst dozens of lines of visually-indistinguishable error handling logic.
- majewsky 6y agoWith 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.