
Why Generics? - johnvega
https://blog.golang.org/why-generics
======
iainmerrick
Maybe this is unfair, but it’d be great if the Go devs could just say
“generics will work similarly to [C# / Java / Swift / D / whatever], except
that we’ll address [problems] with [adjustments]”.

Rather than going through this whole rigmarole of resisting adding generics
too early because all existing implementations are bad, then slowly
reinventing the wheel from scratch, then finally ending up with something
pretty similar to one of those other languages anyway.

It’s OK not to make something completely new and different. It’d be useful to
explicitly say which language(s) you’re borrowing from because you can then
more clearly call out the differences and explain the reasons for them.

~~~
grumdan
> because all existing implementations are bad

I'm also not sure why in OOP-land, generics are this crazy experimental weird
feature, when in functional languages, people figured out how to implement
parametric polymorphism (the original term for generics) in quite reasonable
ways. I get that subtyping adds some complexity, but overall I don't
understand why such a basic way to build abstractions is so controversial in
(some) OOP languages. If anyone has some context on why this is more difficult
to have in Java-like languages, I'd be curious to hear it.

~~~
gizmo686
Inheritance makes generics difficult.

For instance, if A < B (B extends A), What is the relationship betwern
Array[A] and Array[B]?

If you are just reading the array, you would want Array[A] < Array[B]. If you
are writing to the array, you would want Array[B]<Array[A]. If you are doing
both, you want Array[A] to have no relation to Array[B].

This problem doesn't come up in ML style languages because they do not make
use of inheritence.

~~~
justinhj
It comes up in Scala. The solution is to have notation to specify the variance
of types.

~~~
norswap
I think it is Gilad Bracha that said, when the decision was made to include
only covariance in Dart, that variance flies in the face of programmer's
intuition.

He's right. It's easy to understand one level of variance: you can replace a
return type by a subtype and a parameter type by a supertype. (I wouldn't be
surprised that many programmer don't undestand this.)

Two levels already requires some deep thinking (assuming definition-site
variance: `List<Object>` or `List<String>` as a return type / parameter type,
was is allowed to replace it?

More than that? (`List<List<String>>`) Hahaha, good luck.

And by the way, Java has notations to specify the variance of type, but only
at the use-site, which is different from doing it at the definition site (both
enable expressing things the other can't do... but you can actually have both,
as I think is the case in Kotlin, though there are some limitations).

~~~
clhodapp
I'm not really sure what you mean. Variance just changes what is and is not a
subtype/supertype. If List is covariant then List<T> is a subtype of List<U>
if T is a subtype of U. So then, by induction, List<List<T>> is a subtype of
List<List<U>> if T is a subtype of U. I'm not sure what's hilariously hard to
follow here...

~~~
norswap
Good point, it's a bad example because we assume we're just combining
covariance which is intuitive.

Nevertheless, I have a point because:

1\. Things get harder with contravariance. 2\. Things get harder when you mix
covariance and contravariance.

The prototypical covariance class is Producer<T> (with method produce()
returning T) while for contravariance that's Consumer<T> (with method consume
taking a T as parameter).

Assume each class has a superclass (Consumer0<T> and Producer0<T>) and a
subclass (Consumer2<T> and Producer2<T>). Assume V extends U extends T.

Can you list the subclasses and superclasses of Consumer<Producer<U>>?

Personally, I have to think carefully about this for a minute or so, and I've
been there before a couple times.

This is not an especially complex scenario either. I've seen things get worse
in practice.

~~~
clhodapp
Ah, I can figure it out pretty easily for that example too but probably only
because I am pretty familiar with variance and you chose really generous
names. I personally find the reasoning about variance becomes a lot easier if
you stop thinking about the definitions and start thinking about what you
should be able to do. A producer of a subtype is technically also producing
the supertype. A consumer of a supertype can totally consume the subtype.

------
jsgo
Generics with Reflection was the first gut check I experienced while working
after completing college and getting an ASP.NET job. Like 2-3 weeks into said
job.

Had to do an application that dealt with 4-5 forms (can't remember). Like 300
fields on the bigger ones, smaller ones 50ish. I started out on one that was
mid-200. I'm coding the way I was taught in school: object set object
properties based on txtWhatever.Text. Like 240ish times. I can't remember how
many lines of code were in this code behind, but it was substantial.

I turn it in, it works. Go me, let me go on to the next one. The senior guy on
the team does one of the smaller forms. But he uses generics and reflection to
basically iterate over all of the fields on the form and sets them to the
ephemeral properties on this generic object in like 8-9 lines of code. Then
there was the rendering code that was vaguely similar.

Added bonus: 99% of his code behind could be copy and pasted over to the newer
forms and handle all of the work related to getting/setting form values. After
the code proved to work for a few weeks, replaced the massive code behind with
call to his code (passing in the form object and the generic to be set and
used later) with the same result and one area to manage code and it isn't an
insanely large code behind file (got better with not one filing everything in
time too).

Not saying generics and/or reflection are a silver bullet (I don't feel they
are. Rarely so do they end up being the thing I go for), but it was definitely
eye opening that straying from "see spot run" code could be advantageous. And
that I wasn't "good to go" already.

------
elpakal
Chiming in here as a Swift dev - I find its generics system incredibly helpful
and end up writing something that uses generics about once a month. To those
Go programmers who think they will never use them - it’s worth a little
learning, and once you do you will find more ways to use them to make your
code more applicable.

~~~
Vendan
Chiming in as a fervent Go dev that's also a huge fan of generics: Generics
are awesome, but always seem to add a ton of complexity. Everyone starts with
just "oh, `func Reverse(slice []T)` is so obvious" kind of thing, but that's
like saying `fmt.Println("Hello World")` is simple. It's simple cause you are
doing a simple thing.

That said, I do want generics to come to Go, just... with an emphasis on what
Go is, not just "here, let's replicate X's generics in Go". I am interested in
the contracts implementation.

~~~
Nevermindmine
> Generics are awesome, but always seem to add a ton of complexity

The team I work in use generics all the time and I'm not sure what complexity
you are referring to. Care to elaborate? Is it some edge cases or are you
talking about from a compiler perspective or something else?

To me, not having generics is like saying let's skip handling bools and just
store them in strings as "true" or "false". It's such a weird thing from my
point of view.

~~~
Vendan
Compiler perspective (fast compiles are a core part of Go, IMO), various
tradeoffs(fast compile? fast runtime? binary size? Pick 1 or 2), and seeing
code bases that get out of control with generics and such.

Note that, for all of that, I'm still in favor of adding generics in Go, as I
do see the value they can add. I'm just pointing out that "bashing" on Go devs
on not knowing what generics are or how they can be useful is both non-
productive and probably generally wrong. Plenty of us are saying "Man, if I
had generics, this would have been less code/cleaner/more reusable!", just the
other various tradeoffs outweigh the actual cost of using a different
language. Go's ability to drop a very junior dev (or just one that has never
use Go) into a codebase and have them be almost immediately productive is
incredible.

~~~
ernst_klim
> various tradeoffs(fast compile? fast runtime? binary size? Pick 1 or 2)

Interfaces are boxed already, so you've paid the price without having type
safety. Simply treat a polymorphic function as if it accepted interface{}.

------
jknoepfler
The decision to overload parentheses to express generic type is the only part
of this spec I find nauseating. It doesn't scan well, and doesn't have a
precedent in any major generic implementation I'm aware of. <, [,
@-annotation... I don't care. Just don't mush it into the function declaration
with the same syntax that encloses parameter.

~~~
weberc2
Agreed, specifically it creates ambiguities in parsing (for computers but
worse: for humans). Given Foo(x), you can’t tell if it’s a function call or a
generic type without knowing what x refers to. You need context from afar to
disambiguate.

~~~
enneff
You can tell if it’s a function call or a generic type based on where it is
used; the local context. Function calls are either statements or expressions.
Types appear in declarations.

~~~
shhsshs

        a := Bar(baz)(buzz)
    

Is Bar a `func(some) func(thing) other` or is it a `func(type T)(some) other`?
You need to know what “baz” is to be able to tell.

~~~
agrajag
Yeah, it's ambiguous, but be realistic: how often are you calling a function
with a function return _just_ to invoke that directly?

You usually won't see much of either sinice the type argument is only
necessary when it can't be inferred.

~~~
imtringued
In Haskell this happens every time you call a function with two or more
arguments.

------
parhamn
That time of week to rehash all the Go Generics comments!

[https://hn.algolia.com/?query=generics&sort=byPopularity&pre...](https://hn.algolia.com/?query=generics&sort=byPopularity&prefix&page=0&dateRange=all&type=story)

~~~
dotaheor
sort by date:
[https://hn.algolia.com/?query=generics&sort=byDate&prefix&pa...](https://hn.algolia.com/?query=generics&sort=byDate&prefix&page=0&dateRange=all&type=story)

------
moomin

        Go 3: Why HKT?
        Go 4: Why homoiconicity?
        Go 5: Why uniqueness and borrowing?

~~~
olooney
What is HKT?

~~~
mrkeen
I'll give the 'why' rather than the 'what'. In most mainstream languages you
take a List<Int> and substitute for List<X> without changing the
implementation of List. But there's another substitution you could have made,
which is L<Int>. HKT allows you to parametrise L over Int, in the same way you
were able to parametrise List over Int.

~~~
icedchai
Thanks for the practical, plain English definition. As someone many years out
of school, it is appreciated.

------
haolez
Personally, I prefer the current interfaces-based solution to generics. It's a
little verbose, but keeps the language simple.

However, I think that the people we should be listening most are the ones
developing huge projects in Go, like Kubernetes. Would having generics with
this new contracts thing make it easier to develop and maintain e.g.
Kubernetes? I'm truly curious.

~~~
YawningAngel
Kubernetes is a transpiled Java project, so yeah, Java-like features would
definitely make it easier :P

I think idiomatic golang works pretty well without generics in most cases, the
big problem for me is that functional programming is essentially impossible
without them.

~~~
yureka
Can you provide some resources on what makes you think Kubernetes is a
transpiled Java project?

That's definitely not the case from what I know/understand...

~~~
tuvan
There is a talk about it you can find here:
[https://fosdem.org/2019/schedule/event/kubernetesclusterfuck...](https://fosdem.org/2019/schedule/event/kubernetesclusterfuck/)

------
twodave
Generics and interfaces go hand in hand IMO, especially in an application with
heavy emphasis on data persistence. This way you can compose a class of some
interfaces, pass it to a persistence layer (using a generic constraint of
something common to all inputs of that layer), and then the persistence layer
can check for all the interface types it cares about saving and pass those
pieces off to whatever lower-level piece of code handles that one thing.

Generics enable you to avoid having 10 slightly different implementations of
the same thing (even if dependencies are shared, you're still going to have 10
copies of plumbing without generics). Being wise about when and when NOT to
use generics is to me the most important factor.

In our shop we tend to not introduce a new generic class/method until
something gets painful (unless it's plainly obvious from the beginning).
Because of this we usually begin to notice and reason about patterns in our
code that seem common enough to warrant refactoring and whether the complexity
of a generic implementation would be worth lowering the maintenance burden of
copy/pasting said pattern all over the place. It's a case by case decision.

Having generics available at least allows us to make that decision for
ourselves.

------
wrs
The examples I’d like to see worked out fully, which he mentions in passing,
are encapsulation of concurrency patterns (parallelization, work queues,
cancelling, etc.). It’s not that big a deal to write Max as a function or even
inline, whereas there are serious practical pitfalls and common mistakes when
doing real work with channels. It would be a lot more effective to fix these
by writing library code rather than writing Gophercon presentations.

------
Filligree
Why generics, indeed?

There must be an answer to this, but I've never seen a good response to why
they aren't implementing parametric types and (single-parameter) typeclasses
instead.

Simplicity? Yes, but generics are hardly any simpler.

~~~
mda
For me, generics make api designer's life harder, but api user's life easier.
A good enough reason for me.

------
mitchellh
It might be fun to share my viewpoint from an angle that's probably fairly
unique.

I've started a number of large, highly deployed Go projects: Terraform, Vault,
Packer, Consul, Nomad, and numerous libraries and other things. I started a
company that employs hundreds of full time Go developers. Go has been one of
our primary languages since Go 1.0 (and I used it prior to that).

Let me start by saying that there are _definitely_ cases where generics are
the right answer. Usually when I talk about generics people tend to assume I
disagree with the whole concept of generics but I certainly do not. Generics
are useful and solve real problems.

Adding this paragraph after I already wrote the rest: this whole comment ended
up sounding super negative. I'm voicing concerns! But, I think that the design
proposal is exciting and I am interested to see where it goes. There are
definitely places generics would be helpful to us, so please don't take my
negativity too strongly.

## Technical Impact

Having written these numerous large, complex systems, I believe there are less
than 10 instances where generics would've been super helpful. There are
hundreds of more times where it would've been kind of nice but probably didn't
justify the complexity of implementation or understanding.

This latter part is what worries me. I've worked in environments that use a
language with generics as a primary language. It's very easy to have an N=2 or
N=3 case and jump to generics as the right way to abstract that duplication.
In reality, the right answer here is probably to just copy and paste the code
because the knowledge complexity of using generics (for both producer and
consumer) doesn't justify it, in my opinion.

As a technical leader, I'm not sure how to wrestle with this. Its easy today
because generics just don't exist so you have to find a way around it. But for
a 150+-sized org of Go developers, how do we have guidelines around when to
use generics? I don't know yet. I guess that bleeds into human impact so...

## Human Impact!

Something that is AMAZING about Go today is that you can hire a junior
developer with no experience with Go nor any job history, have them read a few
resources (Tour of Go, Go Spec, Effective Go), and have them committing
meaningful changes to a Go project within a week.

I don't say this as a hypothetical, this has happened numerous times in
practice at our company. We don't force or push any new hires to do this, but
Go is so approachable that it just happens.

I love it! It's so cool to see the satisfaction of a new engineer making a
change so quickly. I've been told its been really helpful for self-confidence
and feeling like a valuable member of a team quickly.

The Go contract design document is about 1/3rd the word count of the entire Go
language spec. It isn't a simple document to understand. I had to re-read a
few sections to understand what was going on, and I've used languages with
generics in a job-setting and have also been a "professional" Go dev for 9
years.

So what worries me about this is technical merits aside, what impact does this
have on learning the language and making an impact on existing codebases
quickly?

I really like what Ian said about attempting to put the burden of complexity
on the _author_ using generics, and not the _consumer_ calling that function.
I think that's an important design goal. I'm interested to see how that works
out but I'm a bit pessimistic about it.

\---

I have other viewpoints on generics but those are the two primary ones that
stand out to me when I think about this proposal going forward.

~~~
ClayShentrup
I see the use for generics _all the time_. I came from Ruby, where we have
enumerable so you get standard constructs like map, find, first, last,
each_cons, etc. Because Go lacks them, people constantly reimplement these
things with less intention-revealed code using ad hoc for loops. Ugh.

Thus you see very little use of collection pipelining in Go.
[https://martinfowler.com/articles/collection-
pipeline/](https://martinfowler.com/articles/collection-pipeline/)

Generics are such a powerful and useful idea. Bring it on.

~~~
steveklabnik
Your parent is quite familiar with Ruby. :)

------
aczerepinski
Mixed feelings about this. One of my favorite things about Go is that it's a
small and relatively simple language. It's a "fast enough" language without
the steep learning curve of Rust. Too many features that make sense
individually could change the calculus to "might as well use Rust".

~~~
aldanor
I'm not so sure about the "steep learning curve of Rust" stereotype anymore.
If you are comfortable with low-level programming languages in general, in a
few days you can get yourself started fairly quickly with Rust to the point
where you will still battle with compiler re: borrowing and related things,
but will be able to write functional code. Coming from pure Python/JS will be
tough, but it will be the same with any other low-level language.

~~~
aczerepinski
My work is a Ruby/JS shop, and we have some Go in production as well. We
definitely need a little hand holding to ramp anybody new up on the Go
codebases. In many cases our devs haven't used types, pointers or any
equivalent of goroutines & channels. I've written just barely enough Rust to
say there are even more concepts that would be new to my team.

Even with Go being comparitvely simpler, I could go either way on whether it
was the right choice to add it to the stack.

~~~
LandR
> In many cases our devs haven't used types, pointers or any equivalent of
> goroutines & channels.

How do you manage to get a job as a developer without having ever learned this
stuff?

Are these people that are just self taught straight to javascript / ruby?

I mean, are CS course nowadays so bad that students come out of them without
understanding things like type-theory, pointers etc

~~~
aczerepinski
To be honest, this response feels a bit aggressive and dismissive to me.

Many of my coworkers (myself included) entered the profession through
bootcamps. Others came up during the PHP/Wordpress to Ruby/Rails era of web
development, and never had a reason to learn languages like C++ or Java. I
don't think there's anything to make fun of, or apologize for in this
scenario.

------
fabiensanglard
I hope this doesn't happen. I love golang because it is simple and easy to
read. Both will go away when generic programmer start to write unreadable
meta-programming class which "you don't need to understand, just use them".

I admire golang devs for being opinionated and stand up for the core lines of
their language so far.

I see generic as renouncing these principles.

~~~
tylerflick
This. If I really need generics I'll use a different language.

~~~
takeda
This reminds me the discussion about first version of iPhone how so many
people were advocating why adding copy&paste functionality was a bad idea.

~~~
theshrike79
More like people were advocating against the shitty Copy&Paste phones used to
have.

When it came out, it was possible to C&P pictures to emails and other fancy
stuff that wasn't possible before.

~~~
takeda
I'm quite sure that was possible on android from the beginning.

------
Pxtl
Go has generics. What it actually lacks is user-defined generics.

Which shows the absurdity of the situation. The fact that it has generics
demonstrates that generics are a useful and important feature. And yet they
think their provided generics cover every possible use-case of generics that
you will reasonably need in to use in Go.

~~~
Vendan
And yet, the core devs have never said they don't want generics, only they
didn't want a poor implementation.

Also, there's a bit of hilarity about commenting this on a blog.golang.org
where the first sentence is "This article is about what it would mean to add
generics to Go, and why I think we should do it." being posted by a core Go
dev....

------
zeveb
Not certain I like that this is now valid Go:

    
    
        func Foo (type T) (t T) (t T, err error) { … }
    

Seems like an awful lot of parentheses in a single line!

It's a bit tricky to read, because 'generic function' here means something
subtly different from what 'generic function' means in CLOS …

~~~
mseepgood
It's not more parentheses than in a method definition:

    
    
        func (a A) Foo(x int) (n int, err error) { … }
    

Also your line isn't formatted properly. It should be:

    
    
        func Foo(type T)(t T) (t T, err error) { … }

------
merlincorey
As a functional leaning programmer, I think it's striking that the resulting
draft is essentially a curried function whose first parameter is the type!

    
    
        func Reverse (type Element) (s []Element) {
            first := 0
            last := len(s) - 1
            for first < last {
                s[first], s[last] = s[last], s[first]
                first++
                last--
            }
        }
    

This is later called like:

    
    
        Reverse(int)(s)
    

Which if this were a curried function, would also be callable like:

    
    
        Reverse(int, s)
    

Now I wonder if facilities for currying functions might be a higher level
addition that could result in the same thing (so long sa we can pass bare
types, which is part of this change as well).

~~~
mcguire
I hate to tell you, but you're on your way to dependent types.

------
baby
I have two comments to make about this proposaL:

1\. The type should indicate a generic, not a new syntax. This is better
because it is easier to parse for the human eye. For example:

    
    
      func Reverse(first _T, second _T)
    

2\. Since all of what generics are is a compile-time code generator, I suggest
that Golang forces developers to explicitly list what types are using the
generic:

    
    
      generics(Add) = {int, string, car, food}
      func Add(first _T, second _T)
    

This list can be added to, after importing the package:

    
    
      Import “thing”
    
      generics(thing.Add) += {stuff}
    

This makes code very explicit about its generic functions. It also allow
readers to understand exactly where the function is used.

------
jayd16
If I'm understanding correctly, contracts are a way to implement compile time
duck typing? If that's the case I think its a pretty neat twist on generics.

------
SomaticPirate
One of the things I like most about this is that Ian includes the simple
mistake in the first function. It’s a bit humbling and acknowledges the fact
that even the best of us often make trivial mistakes. It also helps make the
point that even the simplest code needs a basic test and adds another argument
in favor of generics on the premise of duplicating tests.

------
wwarner
I feel pretty good reading this. I like that you can write listMyType :=
List(MyType). I'm still a bit dubious about contracts; they're so similar to
interfaces. If there was a way to derive or relate a contract to an interface
that would help me.

------
sp527
This process took way too long. I've already moved back to Python3 and am
super happy with it. The truth is most software doesn't really need the
performance benefit Golang offers and you can code up something in Python in
at least half to a third of the time it would take in Golang. Aside from
agility, there's one other benefit that imo matters a lot: reduced LoC. If
there's one thing I've learned in my career, it's that you can never really
have too few lines of code, provided it achieves the same result as a
hypothetical more verbose alternative.

I will admit though that I miss Go's CSP implementation and error-handling
convention. Maybe I'll come back to it in the future after they add generics
and fix the dependency system.

~~~
mcguire
Can I sell you some Pony: [https://www.ponylang.io/](https://www.ponylang.io/)

------
clamprecht
Such a succinct article. I wish journalists could explain things this well.

------
sansnomme
I think another area of Go that could use improvements is a more portable
standard library optimised for embedded and OS dev. A lot of people want to
use Go as a "systems language" and do drivers etc. in it. But the standard
library don't have good support for freestanding, or at least it's not a
priority. C and Rust and other languages designed for usage in a non-hosted
environment have very clear delineated areas of runtime that requires
assembly, manual interfaces for IO/memory allocation etc. Go's runtime by
default assumes the presence of an operating system.

~~~
jerf
"Go's runtime by default assumes the presence of an operating system."

It also assumes the existence of several megabytes of runtime and enough RAM
to feasibly use GC, which if nothing else is probably a real mess when it
comes to drivers.

What you probably need, rather than being a second-class citizen of the main
Go language indefinitely, is a separate dialect that is close to Go, but can
go its own way if it makes sense, like:
[https://tinygo.org/](https://tinygo.org/)

~~~
sansnomme
There is nothing wrong with GC. There exist plenty of network stacks in
production that are written entirely in Go (See Docker/Kubernetes et alia).
There are also operating systems that have GCs, such as Oberon or the few C#
OSes written by MSFT and others. As long as care is taken to isolate hard
real-time requirements when needed, a GC is perfectly fine. There is a real
advantage to Rust's style of explicitly marking no_std. After all, what's the
point of using stuff like tinygo (other than for performance/resource reasons)
if it cannot run most of the existing Go libraries?

------
jordiburgos
This looks as an strategy to keep people (and HN) talking about Go.

------
mlevental
why are people obsessed with simplicity? there's a quotation my Einstein that
I like to keep in mind: "make things as simple as they can be but no simpler".
the implication being that if you make things too simple then you actually
break things. lack of generics makes for software that's actually more complex
than it needs to be. Take for example Swift: lots of complex features
(protocols, all manner of functional transformations, generics, enums,
structs, iterators, objects with many method qualifiers, etc) but really nice
and efficient to program in.

~~~
dimgl
I have yet to find one practical application for generics in the apps I've
built in Go.

~~~
mlevental
That's because you write a particular kind of program. Notice that there are
no good ORMs or numerical libraries. Both of these are use cases for generics.
Of course it doesn't help that the go community is convinced that ORMs are
evil (which is just posthoc rationalization for being unable to write one).

~~~
dimgl
Developers think ORMs are evil because they've had horrible experiences with
ORMs in general. I'm one of them. The only ORM that I enjoyed using was
Dapper, and it's barely an ORM.

~~~
runevault
Dapper really is such a weird edge case. You still write all the sql, all it
does is the conversion from a type to the input parameters and the returned
rows into objects where the row names match the parameters of the class.
Frankly I feel like that's the right way to build ORMs in all languages that
have the facilities to manage it (and maybe those that don't you pass in a
function pointer to do the dumping of rows into type for you)

~~~
throwaway8879
The sqlx package is a similar Go wrapper around SQL. Very handy for scanning
into structs.

------
mcguire
" _This article is about what it would mean to add generics to Go, and why I
think we should do it. I 'll also touch on an update to a possible design for
adding generics to Go...._"

This is a situation where _who_ is making the proposal is more important than
the proposal.

" _By Ian Lance Taylor_ "

Oh. Ok. I guess it's worth reading then...

------
013a
The proposed syntax feels like a caricature to me. That something like this
could be easily possible:

    
    
        func (c Connection) Read(type T Writeable)(into *T) (int, error) {
    

This is quite securely inside shark-jumping territory.

Also; I haven't seen Rob Pike's name really anywhere in these blog posts or
discussions, or on any recent Go blog entry. Is he still involved with the Go
project day-to-day? I always got the impression that he was one of the bigger
anti-generics voices on the team internally.

~~~
monkeyfacebag
As far as I can tell, the latest proposal draft forbids type parameterized
methods. One must admit the type parameter to the receiver or define a type
parameterized function. I am making no claims about your broader point, only
clarifying that your example is not permitted by the proposal draft. See
[https://go.googlesource.com/proposal/+/4a54a00950b56dd009648...](https://go.googlesource.com/proposal/+/4a54a00950b56dd0096482d0edae46969d7432a6/design/go2draft-
contracts.md#methods-may-not-take-additional-type-arguments)

------
phlakaton
I do not think generics should be added to Go. It does minimalism and it does
it tolerably well. Yet I enjoy using generics in other programming languages.
If I had my druthers I'd be in Haskell-land in more than my spare time.

Hence, my modest proposal: Add generics, but make it a brand-new programming
language with a totally different name.

Sadly, the name Blub is already taken. I propose we call it Glop. Or perhaps:
Gong.

