5 ms·
The biggest go problem in practice is ironically omitted in both blog posts: Verbosity of error handling! There should be a shorthand for returning if last re
by vl 3y ago
The biggest go problem in practice is ironically omitted in both blog posts:
Verbosity of error handling!
There should be a shorthand for returning if last ret value is non-nil in one line. Otherwise all you code is littered with:
if err != nil {
return err
}
and it makes it four times as long and way less readable as a result. This needless verbosity really reminds me of Java.
Also, go fmt is not opinionated enough! There really should be one way to line break and max width. Right now you can't rely on it to magically format it as it "should be" and fire-and-forget when typing.
- candiddevmike 3y agoYour code shouldn't be littered with that though, those errors should be wrapped or have some kind of logging/handling associated with them. If you find yourself just returning err all the time, you're not doing it right, IMO.
- vl 3y agoIn practice if you look into existing codebases, it is littered. defer is used for RAII-style clean up, so in 95% of the cases it's just return the error and that's it.
- sethammons 3y agoReal world code base developed over a decade. Handles billions of emails. Searching our prod code, "naked" if-err-return-err showed up in about 5% of error handling cases, the rest did something more (attempted a fallback, added context, logged something, metric maybe, etc). If you are doing a naked return you are gonna have a bad time.
- didntcheck 3y agoIf only a language could have a built in feature to propagate an error up the call stack, recording its context as it goes! It's always surprised me how negative of a reception checked exceptions had, since they provide the forced handling (or explicit propagating) of (value, err) or Result<T, E>, but with an automatic stack trace and homogeneous handling across the ecosystem I imagine some of the disdain in Java specifically came with how unergonomic they are with lambdas. Either you don't allow them at all, like in most standard library functional interfaces, or you do, but now every caller has to handle a generic Exception. I guess what was really needed was being able to propagate the "check" generically, e.g. <T, E> T higherOrder(Supplier<T throws E> fn) throws E { return fn.call(); } So a call site of higherOrder would only be checked as far as fn is I'm unsure if that's even possible to do (and if other languages have done it) or if it leads to undecidability. I'm very rusty on PLT
- gaganyaan 3y agoChecked exceptions suck because they're implemented in Java, where you have to deal with Java. The moral equivalent in Rust of "Result" is great, because the language was designed to handle it nicely. You're right that lambdas are a part of it. I can chain together `.map`, `.and_then`, and `.transpose` nicely with closures even if there's Results and Options in the mix, but that would be godawful in Java.
- earthboundkid 3y agoAs a factual matter, both blog posts mention the verbosity of error handling. The second one even specifically mentions wanting Zig's try, which is shorthand for returning early if the error value is not nil.