Why no generics in Go?

32,744

Solution 1

this answer you will find here: http://golang.org/doc/faq#generics

Why does Go not have generic types?

Generics may well be added at some point. We don't feel an urgency for them, although we understand some programmers do.

Generics are convenient but they come at a cost in complexity in the type system and run-time. We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it. Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly.

This remains an open issue.

Solution 2

Approved proposal for generics was implemented for the Go 1.18 release, which came out in 2022 mid-March. Source: https://go.dev/doc/tutorial/generics

"Go 2"

The generics design started under the umbrella of Go2, first at https://blog.golang.org/go2draft and there were several more draft specs over the next 3 years.

Go 1

Russ Cox, one of the Go veterans wrote a blog post entitled The Generic Dilemma, in which he asks

…do you want slow programmers, slow compilers and bloated binaries, or slow execution times?

Slow programmers being the result of no generics, slow compilers are caused by C++ like generics and slow execution times stem from the boxing-unboxing approach that Java uses.

The fourth possibility not mentioned in the blog is going the C# route. Generating the specialized code like in C++, but at runtime when it is needed. I really like it, but Go is very unlike C# so this is probably not applicable at all…

I should mention that using the popular Java 1.4 like technique of generic programming in go that casts to interface{} suffers from exactly the same problems as boxing-unboxing (because that's what we are doing), besides the loss of compile time type safety. For small types (like ints) Go optimizes the interface{} type so that a list of ints that were cast to interface{} occupies a contiguous area of memory and takes only twice as much space as normal ints. There is still the overhead of runtime checks while casting from interface{}, though. Reference.

All projects that add generic support to go (there is several of them and all are interesting) uniformly go the C++ route of compile time code generation.

Solution 3

Actually, according to this post:

Many people have concluded (incorrectly) that the Go team’s position is “Go will never have generics.” On the contrary, we understand the potential generics have, both to make Go far more flexible and powerful and to make Go far more complicated. If we are to add generics, we want to do it in a way that gets as much flexibility and power with as little added complexity as possible.

Share:
32,744
Admin
Author by

Admin

Updated on January 28, 2022

Comments

  • Admin
    Admin over 2 years

    Disclaimer: I've only played with Go for one day now, so there's a good chance I've missed a lot.

    Does anybody know why there is no real support for generics/templates/whatsInAName in Go? So there is a generic map, but that's supplied by the compiler, while a Go programmer can't write her own implementation. With all the talk about making Go as orthogonal as possible, why can I USE a generic type but not CREATE a new one?

    Especially when it comes to functional programming, there are lambdas, even closures, but with a static type system lacking generics, how do I write, well, generic higher order functions like filter(predicate, list)? OK, Linked lists and the like can be done with interface{} sacrificing type safety.

    As a quick search on SO / Google did not reveal any insights, it looks like generics, if at all, will be added to Go as an afterthought. I do trust Thompson to do way better than the Java guys, but why keep generics out? Or are they planned and just not implemented yet?

  • amoebe
    amoebe almost 12 years
    As a Go beginner, I wonder what "the empty interface to construct containers" is?
  • poolie
    poolie almost 12 years
    @amoebe, "the empty interface", spelled interface{}, is the most basic interface type, and every object provides it. If you make a container holding them, it can accept any (non-primitive) object. So it's very similar to a container holding Objects in Java.
  • Einstein
    Einstein almost 11 years
    @poolie Can you elaborate? For instance, who's "them" in "holding them"?
  • poolie
    poolie almost 11 years
    "They" are "objects implementing interface{}". A Go []interface{} is similar to a Java Object[]: an array each of whose slot contains any kind of object. A map[string]interface{} holds arbitrary objects indexed by a name.
  • tbone
    tbone over 10 years
    @YinWang Generics are not that simple in a type inferred environment. More importantly; interface{} is not equivalent to void* pointers in C. Better analogies would be C#'s System.Object or Objective-C's id types. Type information is preserved and can be "cast" (asserted, actually) back to its concrete type. Get the gritty details here: golang.org/ref/spec#Type_assertions
  • Ian
    Ian over 10 years
    @tbone C#'s System.Object (or Java's Object per se) is essentially what I meant by "C's void pointers" (ignoring the part that you can't do pointer arithmetic in those languages). Those are where the static type information gets lost. A cast will not help much because you will get a runtime error.
  • Chris Pfohl
    Chris Pfohl over 10 years
    @Yin, there's a ton of discussion on go-nuts about generics. The problem for them is the hidden costs associated with boxing and unboxing by using a Java or C# like generics system. The problem with template expansion like C++ is the executable size and complexity it adds to the compiler, which right now is blazing fast because of the design decisions they've made.
  • Cubic
    Cubic over 10 years
    @ChristopherPfohl D's templates seem to have quite a bit less of compile time overhead, and normally you don't generate more code with templates than you would normally do otherwise (you could, in fact, end up with less code depending on circumstances).
  • Chris Pfohl
    Chris Pfohl over 10 years
    @Cubic: don't get me wrong. I'm constantly wishing go had generics, I bump into things that would feel cleaner all the time. Have you measured the compile time overhead of templates in D? How do D templates differ from C++'s?
  • ca9163d9
    ca9163d9 over 10 years
    @ChristopherPfohl I think only Java generics has boxing/unboxing issue for primitive types? C#'s reified generic doesn't have the issue.
  • user7610
    user7610 over 8 years
    My solution of this dilemma would be for Go to default to "slow execution times" with the option to profile the program and recompile the most performance sensitive parts in a "slow compilers and bloated binaries" mode. Too bad that people actually implementing stuff like that tend to take the C++ route.
  • BMiner
    BMiner over 5 years
    It was mentioned that small types (i.e. int) that are stored in []interface{} use 2x the RAM as []int. While true, even smaller types (i.e. byte) use up to 16x the RAM as []byte.
  • John Z. Li
    John Z. Li about 5 years
    There is actually no dilemma with the C++ approach. If a programmer chooses to write template code, the benefit of doing so must overwhelms the cost of slow compilation. Otherwise, he could just do it the old way.
  • user7610
    user7610 about 5 years
    The dilemma is about which approach to chose. If you resolve the dilemma by going the C++ approach, the dilemma is resolved.
  • jub0bs
    jub0bs almost 4 years
    If you're reading this answer today, be aware that contracts have been dropped from the draft proposal: go.googlesource.com/proposal/+/refs/heads/master/design/…