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.
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.
I'm sorry but I couldn't read past this.
> I guess I shouldn't be promoting language-bashing, but +1 for calling Go an unacceptably crippled edifice :)
https://old.reddit.com/r/rust/comments/dh4rcz/my_favorite_ru...
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.
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.
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.
Someone describes Go as "unacceptably crippled" while Uber engineering has 1500 microservices written in Go, making it their primary language.
Uber on the other hand has many languages available yet picked Go. So they certainly don't think it is "unacceptably crippled".
Switching to Go was an educated decision. Not a continuation of what was there.
https://www.quora.com/What-is-the-technology-stack-behind-Ub...
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.
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 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.
Go shouldn't be Rust. We already have Rust. Though while I say that, I'd still hate to have to use Go.