Gotta admit, that really is a cute example. However, I was a bit surprised when the author described Go as "unacceptably crippled." What is he referring to?
Go is simple to the point where it annoys a lot of programmers, especially programmers who like to do fancy stuff with their programming language (the kind of person that's attracted to Rust, for instance).
I’m mostly working with Rust, and I really like it, and I can even understand why WRITING Golang can be frustrating at times, but it should be clear to everyone that Golang is the best language to READ.
> it should be clear to everyone that Golang is the best language to READ
I often see Go functions with a large number of lines- many of which are noisy boilerplate error handling. Combine that with terse variable names, type inference and it's straight up tiresome to filter out the important parts. These functions aren't even doing all that much.
There is a healthy middle-ground between excessive abstraction a la Enterprise Java and what Go offers.
I completely disagree, coming from a Java and C# background.
There are nice aspects to reading Go, but any function which does some kind of error-prone operation is so hard to grok, it gets tiring - the actual purpose is constantly interrupted by 'if err := nil' so much.
And gods help you if there is some actual non-trivial error handling going on, as you've generally learned to gloss over and can easily miss that one place that actually does something with an error other than log and return.
Also, while admittedly rare, trying to review code that needs to copy structs around, if they also involve pointers or slices, is just hell.
The usual suspects for things missing from go are the following: Generics, sum types, match statements, tuple types, compile-time data-race detection, type-safe concurrent-maps, hygienic macros, immutable types/references, functional constructs such as 'map', 'filter', or monads, marker interfaces, better error handling, type-inference for consts that isn't garbage, etc.
Less common complaints are that it's missing: object oriented features like inheritance, a configurable gc (as java has), the ability to work with OS threads, c-compatible stacks for fast c-interop, ownership semantics, type-inference for arguments (e.g. as haskell does), operator overloading, dependent types, etc.
The list of things in the first set can mostly be summed up as "go has a worse type-system than C++/rust/etc, something much closer to java 1 before generics, or c". Basically, the language is intentionally crippled because it intentionally ignores advances in type-theory that have been shown to allow expressing many things more safely.
For example, sum types and match statements make modifying code much safer. People will write switch/if-else-ladder code to do exactly the same sort of thing even without them, the code will just fail at runtime rather than compile-time when a new variant is added or one is not handled by accident.
Go code feels very low-level to me, and very boilerplatey. In Rust I can write code that in almost the same way I write JavaScript (but with added type annotations), but Go makes me deal with all the little details, and makes it hard to abstract things neatly.
Lack of generics is a big part of the issue. But more generally the focus on "simple" code means that more sophisticated abstractions are actively eschewed, and personally I find this makes writing Go code quite frustrating.
Your comment is weird.
The one making you deal with the little details should be rust, e.g go is garbage collected.
Secondly, javascript + type annotations is typescript.
Memory management is not the only type of “little detail.” For instance, rust provides common collection operations (filer, map, find…) in the standard library. In go (AFIAK), you need to hand-write a loop for each. IMO, the rust version is takes much less mental bandwidth to write and understand.
rust provides common collection operations (filer, map, find…)
Those are just standard functional methods available in most languages.
Go indeed is noteworthy for it's lack of features.
Businesses often prefer poor languages with lots of cheap programmers readily available to the opposite, because this lets them easily trade off quality against price. Want it done cheap and fast? Get a freshman intern to write it in PHP or JavaScript; if you later want quality, you can then hire some more expensive seniors to fix it up. If you pick Haskell instead, it may be more reliable upfront, but you also have to pay the full price upfront.
Go was explicitly designed to be a poor language of this sort, as evidenced by the infamous Rob Pike quote:
> The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
In other words: a language that makes programmers fungible. And how did they accomplish this? By omitting features and barely going for the lowest-common denominator of the languages listed, disregarding any reasons other languages may have for their more ‘advanced’ features like generics. Hence, crippled.
(Frankly, I object more to describing Scala as ‘the most complex edifice’.)
I'm a big fan of scala and really enjoy the language. That being said, the scala community does sometimes advocate an approach that's pretty over-engineered.
There is an implicit "for my use-case" following "unacceptably crippled". So, go is not "unacceptably crippled" for the use case of creating a ton of small, simple, easily maintainable services at Uber, but it might be "unacceptably crippled" for the use case of having fun with type systems, or whatever the author was interested in at the time they were considering go as an option.
The paragraph starts with "The beauty of programming language design".
Even the most charitable interpretation would conclude it's speaking in broad terms and not just "for my use case".
Full paragraph:
> The beauty of programming language design is not building the most complex edifice like Scala or making the language unacceptably crippled like Go - but giving the programmer the ability to represent complex ideas elegantly and safely. Rust really shines in that regard.
Many teams just start with what they know and then that sets the tone. It no way means that the language is better. Amazon uses Java. Does that mean it's better than Go ? Popularity paints an incomplete picture at best.
I can speak as someone who is building a microservice application in Go and was actually part of the decision to use Go, rather than Java or C# which we traditionally used.
I also find Go-the-language unacceptably crippled. Unfortunately, Go-the-runtime is the only best runtime for microservice-based applications, if you want a GC, especially if you want to run the system on limited hardware.
All the other options are either too bloated to comfortably spawn in large numbers (Java, C#, Node, Python, Ruby take too long to start, use too much RAM , and/or give you too large containers), or are too new and unproven (Nim).
So, we chose to use the inferior language and line with a small hit to productivity (language choice has little impact on productivity after the learning stage anyway) for the superior runtime system.