Hacker News new | ask | show | jobs
by rogpeppe1 4151 days ago
FWIW Go does implement a significant subset of generics in a type-safe way. For any parametric type P[T], if P has no public methods or fields that mention T, then Go can implement it by allowing an interface (not necessarily interface{}) type for T. As long as the implementation of P does not upcast T values (something which is generally frowned upon, although tolerated in some circumstances), this will be as type-safe as in any language with parametric polymorphism.

For example, bufio.NewReader would probably, in a language with generics, be phrased as a type with respect to a type parameter. Something like (in bastard Haskell)

    class Reader a where
        Read :: a -> [Char]


    newReader :: (Reader a) => a -> BufioReader a
In Go, it's:

    package bufio
    func NewReader(r io.Reader) *Reader
The interface argument is implicitly a type parameter here.

This subset of generics covers a wide range of software components, even if it doesn't include the usual container types.

1 comments

I think it's important to think of these features in terms of their smallest possible descriptions. One mistake with Java, I think, is that "inheritance" is how you do both polymorphism and composition (I know you can do either without inheritance, but it's especially a pain to do composition without).

With Go, polymorphism is done with interfaces. Composition is done with embedded fields (and the very convenient method promotion).