The problem, I have with the sentiment (which I grant is largely me over reading into it) is that a lot of the things people think of as noodling or a waste of time, are the central problems in more complex environments. Making sure your program is correct is very important in some environments. Making it easy to express complex domain knowledge as a subset of a programming language is a huge win in some environments.
That isn't a lack of getting things done, thats just more complex logic requirements.
But in C++, those are decisions you might make in parsing a config file, or in managing a simple table of sessions, or adding an LRU cache to something. You can't get away from the decisions. I have an array of stuff, and I have to decide, "do I want a list, an slist, a vector, or a deque, and what the fuck is a deque?". 98% of the time there is one sane decision that is so close to optimal that it's not worth tinkering with.
In Go, for prosaic, routine code, those decisions have been made for you. You have to go just annoyingly enough out of your way to second-guess those decisions that you almost never do, and you're almost always better off for not having to do it.
I'm currently working on a project (WebRender) in which we keep using the standard library hash table in the first cut of code whenever we need an associative lookup table, and every time we use it it keeps coming up #1 in the profile. Almost every single time. We then have to switch to another, more optimized data structure, and generics really help here so that we can reuse these data structures. In fact, if we didn't have them, we'd probably be sunk.
This just isn't as much of a big deal as people think it is. Go makes it a drag to use a custom container, but it doesn't make it hard, and that might be how it should be!
> This just isn't as much of a big deal as people think it is. Go makes it a drag to use a custom container, but it doesn't make it hard, and that might be how it should be!
I believe you that it wasn't a big deal in your case. But I disagree with your general claim. I think you're extrapolating from your use case to claim that generics aren't important (vital, in some cases). I'm saying that, in my use case, they are.
If the default doesn't work for some reason then I can tackle that problem but at that point it usually is core to the problem I'm working on.
For some people Go is anything but frictionless though. They spend all their time in Go fuming that their favorite abstraction isn't there. For those people my experience doesn't translate.
gofmt, for instance, is uncontroversial. Taking the decisions about how to format code away from developers and standardizing it is widely seen as a win (a win Python flirts with as well).
Well, there's a lot of other things in Go that have been pre-decided for you, not just the formatting. The net effect is that you don't have to waste time:
* thinking about designing a DSL for your programming problem (DSLs in Go require parsers)
* designing a class hierarchy to express your programming problem
* choosing between event-loops and callbacks or pools of threads
* picking the right associative container library (do I want a red-black tree? a hash table? a trie?) for routine coding problems
These pre-decisions can feel confining, but I think for a lot of developers Go reveals that those decisions were usually a waste of time. When you actually hit a place where you need a red-black tree, it's not that big of a deal in Go to bring one in. You're just not going to do that for your session store or for a simple lookup cache --- which is, I think, what a lot of people who can't stand Go's lack of generics would be doing.