That's a feature, not a bug. It means I don't have to deal with anyone's 'clever' code.
It's not about saving the compiler work at all, it's about saving the hundreds of humans who have to read your code after you the work of understanding the abstractions you created.
A little duplication is better than the wrong abstraction, and I've seen far more subtly wrong or obfuscating abstractions than duplication in code I have to manage. Go is definitely not perfect, and sometimes it's plain wrong about this (I don't particularly like the go error handling and hope it improves), but there is a reason for discouraging certain types of abstraction and encouraging verbosity and boring code instead, and it's not to save the compiler time.
Abstractions like map and filter that have decades of use and countless pages of research behind them are not the wrong abstraction. You are more likely to get the wrong abstraction by forcing programmers to create their own abstractions instead of letting them use well-known ones that have been refined over many years.
I'm not sure anyone was opposed to map (that wasn't under discussion), not all abstractions are bad, however a flexible language makes code easier to write but harder to read, a rigid language makes code harder to write but easier to read. I prefer ones that are easier to read, even at the expense of a little verbosity.
I'm not saying Go is the best of all possible worlds (I would like to see generic functions like map too, or things like sum types for errors), just that there are good reasons for the decision to exclude some opportunities to build abstractions (for example I'm happy go eschews inheritance), and abstraction is not an unmitigated good. I've seen far more bad abstractions built than code duplicated when reading code in any language, so limiting abstractions is not always a bad thing.
> A little duplication is better than the wrong abstraction
Besides the notion of "The wrong abstraction", which is sometimes used as a proxy for "Abstractions I don't want to learn", we're discussing about language level abstractions here. The article you quote criticizes user level abstractions.
Language-level abstractions have a decent enough track record that we can assess them. Go even uses some of them: GC is, after all, an abstraction.
There would also be a lot to say about what the "little" in "A little duplication" means.
This. Either you check in a DSL, or you try to compile the DSL to boilerplate in your head and check that in, then everyone has to try to read the boilerplate and try to infer what the DSL would have said.
It's always strange watching programmers defend go's obvious deficiencies. I mean, this sort of "appeal to simplicity" could be used to defend anything.
The reality is most go programs are (1) very difficult to understand because error handling swamps their logic and (2) end up reinventing exceptions anyways, albiet poorly and (3) inevitably end up leaking resources because go's "error handling strategy" doesn't ensure resource cleanup.
We can observe this and measure this quite clearly in non-trivial go codebases.
Eventually the go dictatorship will relent and provide exceptions. At that point all the people who praise the existing broken model will happily praise the new approach and denounce the existing brokenness.
I wholeheartedly agree with you. Go got a lot right (concurrency, deployment), but some parts of Go's language design are missing the last two decades of programming language history. To me, arguments supporting Go's error handling approach alway seem a little bit like people are rationalizing a horrible mistake.
It's not about saving the compiler work at all, it's about saving the hundreds of humans who have to read your code after you the work of understanding the abstractions you created.