> Critics often complained we should just do generics, because they are "easy", and perhaps they can be in some languages, but the existence of interfaces meant that any new form of polymorphism had to take them into account.
I've been noodling on a statically typed hobby language and one of the things I'm trying to tackle is something like interfaces plus generics. And I have certainly found first-hand that Rob is right. It is really hard to get them to play nicely together.
I still think it's worth doing. Personally, I'd find it pretty unrewarding to use a statically-typed language that doesn't let me define my own generic types. I used to program in BASIC where you had GOSUB for subroutines but there was no way to write subroutines where you passed arguments to them. I don't care to repeat that experience at the type system level.
But I can definitely sympathize with the Go team for taking a long time to find a good design. Designing a good language is hard. Designing a good language with a type system is 10x harder. Designing a good type system with generics is 10x harder than that.
> But I can definitely sympathize with the Go team
I don't.
The hardest part in implementing generics is when you support inheritance of implementation.
Go doesn't.
Go had the easiest job in implementing generics.
The only reason why they didn't was not technical: it was ideological and purely based in ignorance, and the fact that most Go designers stopped paying attention to the field of PLT in the late 90s.
All the ML and functional languages don’t seem to have this problem, and a lot of them have Type Systems that are far more sophisticated and capable that go’s.
SML actually has a very simple, unsophisticated type system that isn't anywhere near as expressive as generics in most other languages (Java, C#, Go, etc.).
In SML, there's no way to define a generic hash table that works with any type that implements a hashing operation and uses that hash function automatically. Type parameters are entirely opaque types that you can't really do anything with. To make a generic hash table, the user has to explicitly pass in a hash function each time they create it.
In other languages, you can place a bound on the type parameter that defines what operations are supported and then the operations are found (either at runtime or monomorphization time) based on the type argument.
If you don't have bounds, lots of things get easier for the language designer. But lots of things get much more tedious for the language user. It's probably not a coincidence that every language newer than ML with parametric polymorphism has some sort of bound/trait/constraint/type class thing. But bounds are where most of the complexity comes from.
I do agree SML's type system feels elegant and useful at first, and becomes suddenly quite limiting when attempting the kind of domain modeling or library level genericity you'd do in e.g Java.
On the other hand, isn't the hashmap use case you mention addressed with the module system and functors ? Like the set abstraction described in this SO answer [0].
Wondering where my understanding of your message or SML fall short.
Keep in mind that Scala had been released before golang was. And became popular around the time golang was released. Without GOOG-scale resources behind it.
I've been noodling on a statically typed hobby language and one of the things I'm trying to tackle is something like interfaces plus generics. And I have certainly found first-hand that Rob is right. It is really hard to get them to play nicely together.
I still think it's worth doing. Personally, I'd find it pretty unrewarding to use a statically-typed language that doesn't let me define my own generic types. I used to program in BASIC where you had GOSUB for subroutines but there was no way to write subroutines where you passed arguments to them. I don't care to repeat that experience at the type system level.
But I can definitely sympathize with the Go team for taking a long time to find a good design. Designing a good language is hard. Designing a good language with a type system is 10x harder. Designing a good type system with generics is 10x harder than that.