>I'm going to go out on a limb and guess that you've never had to work in that space. It's really easy to insult Go's solutions
It's really easy to insult my opinion as well. I do have worked in really large codebases.
The only thing where Go helps "really large codebases" is quick compile times. But it is really easy to create a fast compiler when the language is anemic in features, this is no feat at all.
If Go wanted to be useful for "really large codebases" it would have supported good exception handling (take a look at Common Lisp for exemplary exception handling), for a start. And don't get me started on the horrible kludge of using interface{}.
And for "really large codebases" you want to keep mindless boilerplate code repetition -which is the noise that puts haze over the signal- close to zero. Go has many design choices that do exactly the opposite -- increase boilerplate to the max.
Fair enough, and somewhat deserved. (But only somewhat - your tone kind of led me into temptation. Still, I apologize.)
> The only thing where Go helps "really large codebases" is quick compile times.
Which was, in fact, explicitly their intent. In comments on this same article, people have been complaining about how long it takes to compile GHC. How long would it take for Haskell to compile a 10 million line program? For a program that has, say, 50 people working on it, and that lives for 20 years, that adds up to real money.
Now, you could argue that, if go didn't increase boilerplate so much, you wouldn't have so many lines to compile. That's a fair criticism. Still, just focusing on compile times, would you rather compile 10 million lines at Go's speed, or one million lines at Haskell's?
> But it is really easy to create a fast compiler when the language is anemic in features, this is no feat at all.
The "feat" is choosing to focus on compile time rather than on features.
I disagree with you on exceptions. Go's error handling approach means that you only have to worry about your function and the functions you directly call. Java's approach (or worse, C++'s, since the exceptions are unchecked) means that you have to worry about what every function in the call graph can throw. As the size of the program increases, knowing everything that can be thrown by everything you call becomes unreasonable. (I don't know enough about Lisp's approach to know whether it suffers from this problem or not.)