3 ms·
Ouch. Super sorry about the shitty code in the free project you built your business on ;-). Anyway, this was a point of huge debate early on in the developmen
by aboodman 6y ago
Ouch.
Super sorry about the shitty code in the free project you built your business on ;-).
Anyway, this was a point of huge debate early on in the development of Noms. Some team members just could not accept the constant litter of `if err != nil` no matter how many times I repeated that Rob Pike says it's OK. It goes against deeply held beliefs that all programmers internalize early on, for good reason.
It’s probably why some parts of Go internally have also used panics for flow control (the JSON decoder, famously), and just convert them to errors at the boundaries. This was our plan, but we were not careful about protecting all the goroutine launches. As I said elsewhere in the thread I think we would have welcomed working together on this if the Dolt folks had wanted to.
- throw_m239339 6y ago> that Rob Pike says it's OK. I should say, Rob Pike didn't put in the language the features that would have helped alleviate the pain of writing 50,000 times the exact same statement littering Go code bases like a plague. Go errors are purely a convention that is no better than C style error code returns. Not good enough in whatever year Go was designed. There are solutions to that issue that are much more composable than that (options, sum types...). People come to Go for performance and concurrency (although context is another one of these tacked on horrors) and they leave the language because of the crazy ceremonial boilerplate it incurs.
- vii 6y agoRob Pike wrote this about handling errors https://blog.golang.org/errors-are-values https://blog.golang.org/errors-are-values This is like an option type but manually built. Go is painful if you don't want to write high-quality heavily exercised production code. If you do, then you should be considering each error condition. Most code doesn't need to worry about error handling as it will run under close supervision on at most one machine over its lifetime. Go is a nuisance for that.
- apta 6y ago> Go is painful if you don't want to write high-quality heavily exercised production code. That's the excuse that the golang authors give. The fact of the matter, golang is also extremely annoying when writing "high quality production code". golang errors are error-prone, and on more than one occasion we've had instances where errors are mistakingly ignored. This is much worse than exceptions where they have to be explicitly swallowed, otherwise they'd automatically bubble up.
- aboodman 6y agoReally the opposite is true. If you want to know that you have handled every error path, Go is awful because there is no language or compiler support for it at all. Completeness has to be ensured manually, by inspection. Check out Rust's error handling approach sometime for an example of a language that truly values complete and correct error handling. It is a joy. === The reality is that Go doesn't have better error handling because the language designers value the simplicity of Go's implementation more than the simplicity of its interface - a trait that directly flows from its unix roots [1]. This is a fine tradeoff, and the right one for many problems. Go has been extremely successful in large part because of this philosophy. But you should not kid yourself that this is somehow the Right Way to handle errors, just because it's what Go does. Because even Go's designers are actively trying to fix it [2]. [1] https://www.jwz.org/doc/worse-is-better.html https://www.jwz.org/doc/worse-is-better.html [2] https://github.com/golang/go/issues/32437 https://github.com/golang/go/issues/32437
- xyzzy_plugh 6y agoGive 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.
- timsehn 6y agoCEO of DoltHub here, just want to go on the record and say discovering Noms made us realize Git semantics on top of a SQL database were closer at hand than we presumed. It changed the direction we were heading and we like the place we ended up. Sure, the panics sucked but it's over. Happy to figure out a way to get those changes back into Noms eventually. When we changed it, it was unclear anyone would ever work on Noms formally again.