The problem with interface{} is that it makes it pretty much worthless to have a type system at all.
As for saying "they are the same once the code is running", well, duh, of course, but it's completely useless by then.
I don't understand this argument. You need `interface{}` about 1% of the time; somehow it's better to have no type checking than only 99% type checking? Even in the 1% of cases, I've literally never seen a production bug (or even a failed test case) caused by a type error. I'm sure they happen, but I doubt they happen so frequently that adding in a generic type system would be a net gain.
The problem is this: Have you ever worked in a mature codebase with generics, where they haven't somehow been overused? Please tell me where that is!
Point me to a successful statically typed language born after 2005 that doesn't have some form of generics. Go has generics by the way, you just can define your own in user land, which is a stupid limitation.
Class hierarchies, for example, got heavily overused before people discovered that composition most of the time is the better option, exceptions got overused before people learnt to only use them in exceptional cases, and dependency injection and XML (one of the first environments with strong support for it) got overused in Java programs.
Generics are going the same way, if they haven't already (JavaScript modules will get there, too, but that seems at least a generation of programmers away)
Also, the only difference I see between generics (with a bit of 'compile-time reflection') and go generate is that the former may be too magical for some, while the latter requires programmers to do more work (writing special comments to use existing functionality, and writing AST manipulation code to write new ones) and that it generates files only because the compiler wants to see them.
Backing away from specific suggestions, I think it's healthy to recognize that Go has a boilerplate/DRY problem--not just with error handling!--, and it would be nice to address it in some way. If not with generics, then with something.
I'm having a hard time understanding where using generics would cause problems.
C++ templates, sure, but those are much more powerful than just having parametric polymorphism.
C++ templates! I keep on running into places where I'm debugging, then I find myself in a maze formed by template overuse, then debug around that instead.
just having parametric polymorphism
I think that could be workable in Go. I can imagine how debugging that would be straightforward.
The tupled (T, error) return types are a key area I think generics would help. The error-tuples themselves aren't the problem, but rather Go's inability to cleanly handle them. Threading error state around requires repetitive glue code (if err != nil). In some languages, you hide the glue code in monads. In some languages, you hide the glue code in macros. In some languages, generics reduce the glue to chained methods on helper objects. In Go, once in a while you can hand-write a lambda function to manage a closed-over error variable and clean things up a bit, but that's about all you get.