Also, the "I never need generics" made me smile. Sure, one can get by without them, but sometimes, as I said above, it would be really nice to have them.
Admittedly the error pattern is so common that I can imagine people getting very much used to it, but thats not the issue here. The problem is indicative of Go's lack of abstraction power, and its pervasive. There is no difference between `filter`, `map` and a regular foreach - every piece of code that wants to do things like that must re-implement the mechanics of creating new slices and assigning things to members which are accessed using a specific index. So many details - I can't see the forest from the trees!
I see the same kind of noise in legacy messy projects where a piece of code works on multiple abstraction levels and its impossible to think about what a it does without thinking about the mechanics of how it does it.
Given all this I really can't understand how someone can call Go code beautiful and clean. My gut reaction is "this will cause a mess couple of years down the line".
The cost of not having generics in Go is really understated, and it saddens me greatly. With them, Go would be an extremely interesting language. But apparently, the language designers believe that you (the user) are not to be trusted with writing sensible abstractions and therefore are forbidden to do it.
I find that so bizarre. That's on a personal level, I'm not throwing stones.
My two favorite languages before Go came along were Objective-C and Python. Different tools for different problem-sets of course, but Objective-C can quite easily be called insanely noisy.
Go is obtuse, but I find its readability on par with Python in that there's one way to do something, and that way is repeated over and over. I don't have to worry too much about stylistic preferences between programmers, people trying to get fancy while writing code (or trying to show off). Our server code serves thousands of requests per second - I need that code to be rock-solid, not fancy or overtly minimalistic.
You're right, people do get used to the error pattern. I can either handle it, ignore it, or toss it up the stack, and I get to make an explicit decision about that every time.
We've been rewriting critical systems code in Go (from mostly Python) and it's a joy. I am, of course, the (unintended) target audience for Go - a dynamic language dev looking for speed, concurrency, and compile-time safety, along with the simplistic beauty of gofmt, goimports, and so on. But I do find it beautifully simple, if not entirely "beautiful."
Edit: formatting.