Hacker News new | past | comments | ask | show | jobs | submit login

I really don't understand why go doesn't have generics. Shouldn't it be even easier because go has no inheritance? So the problem of covariance and contravariance goes away.

Seems really strange.




There are proposals to add generics soon: https://go.googlesource.com/proposal/+/master/design/go2draf...

It's not a question of whether or not it's easy or hard; it's definitely technically doable.

It's a question whether or not it's desirable. I think the consensus is shifting decisively to saying that it _is_ desirable. The question then becomes how you can assert concepts on a type at compile time.

E.g. for a function add(a T, b T) and a type T, how do we assert that a + b is a valid statement? The draft design shows one approach to this.


> It's not a question of whether or not it's easy or hard; it's definitely technically doable. It's a question whether or not it's desirable.

And everyone not trying to make excuses for the Go-team knows what the one and only answer to that question is.


Rob Pike wrote a bit about it in "less is exponentially more". He points out that generics are used by languages that focus on types and that Go focuses on composition and uses interfaces ( and language buildins ) instead of types to solve problems.


> generics are used by languages that focus on types and that Go focuses on composition and uses interfaces ( and language buildins ) instead of types to solve problems.

Interfaces are (abstract) types, so you can't “use interfaces instead of types”. Go’s use of interfaces is a variation of the “you can only have subtypes of abstract types” approach. Julia is an example of another modern language which also uses this general approach to type heirarchy, which, yes, does correspond to a strong preference for composition over inheritance; OTOH, like most relatively modern non-Go language with this approach, it also has generics. The idea tha generics are mostly used by languages that don't follow this approach is true in the sense that most languages, and therefore most with generics, do not follow this approach. But modern languages besides Go that follow the “composition-over-inheritance, no subtyping concrete types” approach seem to be just as likely as languages which support subtyping concrete types to have generics.

So, as well as not actually explaining anything (generics and composition-over-inheritance don't solve the same problem, so using the latter doesn't explain not using the former even if they did tend coincide in practice), it's doesn't seem to point to a real correlation.


Composition is orthogonal to generics.


>Rob Pike wrote a bit about it in "less is exponentially more".

Which is wrong.

>Go focuses on composition

Clearly false.


How is this false? I agree with this assertion after having used Go extensively for some time. Where Go really shines is when the stdlib offers a nice abstraction (io.Reader, io.Writer, http.Handler) and you can compose your programs from building blocks that use these abstractions. For example, from the http.Handler interface follows directly a middleware interface:

  type Middleware interface {
    Wrap(http.Handler) http.Handler
  }
without requiring any generic types. For comparison, the same thing in Rust would rely on type polymorphism:

  //assuming that Handler is a trait
  trait Middleware<T: Handler> {
    type Result: Handler;
    fn Wrap(handler: T) -> Result;
  }
  //NOTE: Not using impl-trait here to make it clear that
  //two type variables are involved (one type parameter
  //and one associated type).
You could mimic the Go behavior if you box all your traits, which Rust does not like to do because it's not zero-cost:

  trait Middleware {
    fn Wrap(handler: Box<Handler>) -> Box<Handler>;
  }


The current generics proposal includes some form of ad-hoc polymorphism (overloading) on top of standard parametric polymorphism, which complicates things quite a lot.

Also, choosing which compilation strategy to use has a big impact on the compiler architecture (monomorphization? boxing? a mix of both?)


Time and priorities. They didn't have the time until now as their priorities were elsewhere (as they should have been, they were building tools for their own use cases).

You can argue until the heat death of the universe about wether those priorities were chosen wisely, but it's irrelevant now. They built the tools for themselves focusing on what they found to be most important at the time. It's clearly worked out well enough for them and many of us like how Go turned out despite its short comings.


I think the article answers that. There's a whole bunch of design and implementation decisions that would be very different and more complex with generics.


This is really not different from how generics are implemented in many languages, it's almost identical to how haskell implements parametric functions w/ class constraints (i.e. a dictionary w/ concrete functions for implementing the algorithm for a specific set of type parameters is passed): https://www.schoolofhaskell.com/user/jfischoff/instances-and...

The only difference is that haskell generic functions can be specialized and the methods in the dictionary can be inlined: https://wiki.haskell.org/Inlining_and_Specialisation#What_is...




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: