I was thinking about why Go doesn’t, and shouldn’t, have generics. Then it
dawned on me: there are two styles of polymorphism.
The first would be that associated with languages such as Java, C#, Haskell,
etc. These are languages with generics or something similar which allow you to
define types such as List<int>
, Dictionary<string, Thing>
and so on, with
methods/functions that act on a genericList<T>
. This I think of as structural
polymorphism since it is determining what to do based on the structure of a
value.
The other style would instead be associated with Go, Ruby, Smalltalk, etc. These
are languages with a way of determining whether an object has a particular
behaviour, either by querying its methods (Ruby respond_to?
, Smalltalk
respondsTo
) or by defining an implicit interface as in Go. This would be
behavioural polymorphism since it determines what to do based on the behaviour
of a value.
Each style is suited to solving different problems, but neither could be argued
to be more powerful than the other.
I can’t think of a language that supports both styles, but there is a theme. The
dynamic languages favour a behavioural approach, since they have no good way to
represent the type information required for a structural approach; and the
statically typed languages favour a structural approach for the inverse reason,
they are tied to the idea of types as structure.
Go then is the outlier. It is statically typed, yet has a behavioural style of
polymorphism. Perhaps this is the reason the Go authors haven’t shown any
enthusiasm to including something like generics, they have already chosen their
preferred polymorphism.