Furthermore the article presents Go's approach superior to C++ because of the reduced code generation (since it uses a "maptype" struct for the type-specific information) but doesn't talk about the drawback of such an approach: you have additional indirections in the mapping code and the compiler can't inline and optimize for specific types. Of course in some cases that's actually desirable, very large code size can be problematic.
I could also add that you could pretty easily implement Go-style hashes in C++ (actually that's often how you implement generic hashes in C, using helper functions depending on the type) but you can't implement C++-style hashes in Go without hacking the compiler or using codegen.
This is one of the reasons I don't really like the name 'generics', it's a little ambiguous.
> You can't create new parameterized types in Go
Or create functions on parameterized types (without providing concrete type parameters), which is possibly a bigger annoyance than the other one: slices are a thing, but you can't operate on arbitrary slices without reflection. As well as generic types being restricted to builtins, generic functions (e.g. close, copy, len) also are.
func delete(m map[Type]Type1, key Type)
it could have func Delete(type Type, Type1 somecontract) (m map[Type]Type1, key Type)
in there, and a program compiled with Go 2 would have an implied instance of func delete = builtin.Delete(T, U)
in its global namespace for every map with a `delete` used somewhere in the code.The proposal in the 2.0 spec looks promising and I'm looking forward to hopefully being able to play with an implementation sometime.
My guess (and personal experience) is that this would maybe be more convenient to do this via code generation. It's not as ergonomic as generics (well, depending on the implementation...), but still it's less cumbersome and prone to failing at runtime that reflection.
Reflection has its uses and places, but as soon as it gets all over a function then it's time (imho) to look into code generation.