I like parts of Go. It's refreshing. I'm excited for this release. What I don't like is how its weak parts are consistently defended instead of having its shortcomings be acknowledged.
Before any rational analysis and criticism can begin, we need to look at the context of these arguments. I'll do that through some of the comments on this post.
- Issues people bring up are dismissed as non-issues or as personal preference / opinionated, regardless of their impact.
- Critics are asked for rational analysis, but proponents are allowed to use something as airy as "simplicity", a word that has essentially lost all meaning in programming.
- Missteps by representatives / stewards of Go are given the most charitable interpretation, critics less so.
- Finally, in so many cases, counterarguments to critics are dripping in condescension.
I don't think folks are going to get rational analysis. I also don't think they actually want it, whether they realize it or not.
In case anyone is interested, here are my technical critiques of Go:
- Boilerplate increases the surface area that a bug can hide in. The fact that most of the boilerplate is around error handling is especially worrying. Yes, the flexibility of "Errors are values"[1] is nice. But I also don't know any languages where errors _aren't_ values, so the main value add seems to be reduced boilerplate compared to individual try/catches around each function call.
- Go manages to repeat the Billion Dollar Mistake[2]. Things like methods working on nil receivers is cool, but not worth the danger or messiness.
- Even worse, for a language that claims to value simplicity, the fact that nil sometimes doesn't equal nil[3] is... honestly, I can only consider that a bug.
> But I also don't know any languages where errors _aren't_ values
(look, i know you understand how exceptions work, please bear with me)
yes, Exception objects are technically values, but you don't return them to the caller; you throw them to the, uh, catcher. basically, you get a special, second way of returning something that bypasses the normal one! but in the EaV approach, errors just are returned like every other thing.
the uniformity of EaV comes in handy when doing generic things like mapping a function over a collection - don't have to worry if something will throw, because it's just a value! and that lets you go to some pretty powerful places w.r.t abstraction: see e.g. haskells `traverse`.
but yeah, EaV needs some syntactic sugar to reach ergonomic par with exceptions, otherwise you get if-err-not-nil soup :P
Right, so the concept in Go is misnamed. It's not Errors are Values, it's Errors Have Normal Control Flow.
Returning errors makes many things more manageable, definitely. But where they really shine, like in the mapping example, isn't possible in Go. Unless I'm mistaken with how go generics work.
(By the way, I'm a huge fan of how error handling works in Rust and other related functional languages. Definitely not advocating for the classic way of doing Exceptions).
> But where they really shine, like in the mapping example, isn't possible in Go.
oh yeah, definitely! Go's version of EaV with multiple returns is pretty lackluster compared to a proper Result type. afaict it's kind of "the worst of both worlds" -- all of the boilerplate of plumbing errors manually w/ none of the benefits.
Definitely. But Go's boilerplate for error handling is an overcorrection from the implicit propogation. As folks have mentioned, Rust's `?` or Swift's `try` strike a nice middle ground.
That's what I'm saying - any language with exceptions can be treated as if it was all Rust-style Result<T, E>, but with implicit ? after every expression. Well, and E is an open variant (like e.g. extensible variant types in OCaml), unless the language has checked exceptions like Java.
Before any rational analysis and criticism can begin, we need to look at the context of these arguments. I'll do that through some of the comments on this post.
- Issues people bring up are dismissed as non-issues or as personal preference / opinionated, regardless of their impact.
- Critics are asked for rational analysis, but proponents are allowed to use something as airy as "simplicity", a word that has essentially lost all meaning in programming.
- Missteps by representatives / stewards of Go are given the most charitable interpretation, critics less so.
- Finally, in so many cases, counterarguments to critics are dripping in condescension.
I don't think folks are going to get rational analysis. I also don't think they actually want it, whether they realize it or not.