
Proposal: Go should have generics - dsymonds
https://github.com/golang/proposal/blob/master/design/15292-generics.md
======
NateDad
I work on juju ([https://github.com/juju/juju](https://github.com/juju/juju)),
which all told is about 1M LOC. In my almost 3 years on the project, I have
not been bothered by lack of generics, basically at all (and I worked for 10
years in C# on projects that used a lot of generics, so it's not like I don't
know what I'm missing).

Do we have 67 implementations of sort.Interface? Sure. Is that, by any stretch
of the imagination, a significantly difficult part of my job? No.

Juju is a distributed application that supports running across thousands of
machines on all the major clouds, on OSes including CentOS, Ubuntu, Windows,
and OSX, on architectures including amd64, x86, PPC64EL, s390x... and stores
data in a replicated mongoDB and uses RPC over websockets to talk between
machines.

The difficult problems are all either intrinsic to the solution space (e.g.
supporting different storage back ends for each cloud), or problems we brought
on ourselves (what do you mean the unit tests have to spin up a full mongodb
instance?).

Generics would not make our codebase significantly better, more maintainable,
or easier to understand.

~~~
d4rkph1b3r
>Do we have 67 implementations of sort.Interface?

Hahaha. This has to be satire right?

>Generics would not make our codebase significantly better, more maintainable,
or easier to understand.

Generics are _literally_ a form of abstraction. You might as well be arguing
that abstraction doesn't help. Why do you even have subtype polymorphism then?
Why not just reimplement everything? That's not a significantly difficult part
of your job as you said.

One of the best things about Go is it seems to be a strong signaler of the
type of engineering team I avoided.

~~~
NateDad
> >Do we have 67 implementations of sort.Interface?

> Hahaha. This has to be satire right?

Nope.

    
    
        /home/nate/src/github.com/juju/juju$ grep -r ") Less(" . | wc -l
        67
    

(granted, 10 are under the .git directory, so I guess 57)

But in any other language, we'd still have the same 57 definitions of how to
sort a type.... we'd just have 3 fewer lines of boilerplate for each of those
(which live off in the bottom of a file somewhere and will never ever need to
change).

~~~
pklausler
> But in any other language, we'd still have the same 57 definitions of how to
> sort a type...

That claim turns out to not be the case.

~~~
NateDad
Aside from trivial types, like strings or integers, how does the language know
how to sort a list of values, if you don't tell it how to?

Translate this into whatever language you like:

    
    
        Machine {
            Name string
            OS  string
            RAM int
        } 
    

You have 3 places that want to sort a list of machines, one by name, one by
OS, and one by RAM. You're telling me there's a language that can do that
without having to write some kind of code like this for each?

    
    
       sort(machines, key: Name)
    

I don't understand how that's possible, but I welcome your explanation.

~~~
pklausler
Sorting on all three fields in priority order is what I had in mind, and
that's trivial in Haskell by adding "deriving(Ord)" to the data type
definition and then just using the standard "sort :: Ord a => [a] -> [a]".

If you're always going to sort them based on some (other) relation between the
fields, make your type a custom instance of Ord, e.g. "instance Ord Machine
where compare = compare `on` name".

To sort the same type with distinct comparators, you'll obviously need to
distinguish them, as in e.g. "osSort = sortBy (compare `on` os)".

~~~
NateDad
So... you will still need 57 spots in the code where you define how to sort a
type.

Maybe my reference to sort.Interface is confusing people. When I say we have
57 implementations of sort.Interface, that's 57 different types and/or
different ways of sorting one of those types. So, like, sorting Machine by
Name would be one implementation, sorting Machine by Name then OS then RAM
would be another implementation. You write an implementation of sort.Interface
for every type, and for each way you would like to be able to sort it.

An implementation of sort.Interface just requires three methods:

    
    
        Len() int // return the length of the list
        Swap(i, j int) // swap items at indices i and j
        Less(i, j int) bool  // return true if list[i] is less than list[j]
    

It's the implementation in Less that determines the order.

That's not really so different than what you're describing in Haskell, it's
just not part of the type, it's a new type that you convert the original type
into, to pass into the sort.Sort() function (and because the underlying type
is a slice, which is a glorified struct with a pointer to an array, that also
sorts the original value).

~~~
infogulch
It's possible to make one implementation for a type that supports multiple
orderings, at the cost of another indirection [0]. This turns O(N*M)
implementations for N types and M sorting orders into just O(N). (I'm not
counting an inline anonymous function as a new implementation.)

In practice, it's rare to need to sort a slice more than one way.

[0]:
[https://gist.github.com/infogulch/5db15e5ae5cf073f1088033ba4...](https://gist.github.com/infogulch/5db15e5ae5cf073f1088033ba4c714fb)

------
mattlondon
I can feel the pain on the Sort issue. I've personally found sorting annoying
in Go - I had a bunch of structs representing data entities from a database
that all had the same field and I wanted to be able to sort them by this
field.

Seemed like a LOT of work (basically implementing the same sort that was 99%
identical for every struct) or use weird reflection-workarounds to get this to
happen. In Java I would not even given this a second thought and be back to
coding up the important part of the code ages ago.

I am a new go-lang user so would love to know what the best approach to
resolve this is without a) repeating the same thing for every struct, or b)
relying on "unsafe" reflect techniques (since AppEngine rejects code that does
that) - surely sorting structs is a super-common, basic thing for a systems
language? I've seen someone just nonchalantly say "Use interfaces" but I'm not
sure still.

I like the language generally but this is a real "WTF?" moment for me.

~~~
Loic
I had the same feeling first. But practically in my code, I found that ok, you
need to copy/paste a bit first but then if it works it stays there, you are
not "sorting" new kind of "types" every day. The time spent on coding is way
more "around" the algorithms than "within" them.

I suppose that we will see more and more code generators which will
practically remove the need of generics. We already use them without
complaining for serialization in JSON/Protocolbuffer/etc...

~~~
alkonaut
If code generation is used to make up for something missing in a language (be
it generics, metaprogramming etc.) then that's a pretty clear sign something
is wrong.

It's definitely acceptable to use a workaround for a missing feature once or
twice in a language, because no language is perfect, and no language benefits
from being burdened with _all_ features imaginable.

But if a workaround becomes part of the day-to-day workflow, then you are
likely using the wrong language.

Examples could be: using (textual) code generation for generics, or using type
annotations throughout a dynamic language project.

~~~
Arzh
Code generation is not about a deficiency in the language, C++ has templating
but I will often use code generation since you only need to run that once and
templating bloats the compile time for ever.

~~~
nanny
>I will often use code generation since you only need to run that once and
templating bloats the compile time for ever.

Don't you need to compile the generated code?

~~~
Arzh
Yes of course, but compiling the code is faster than generating the code and
then compiling it. Templates are much slower than just compiling code
straight.

~~~
tacos
With the exception of pathological metaprogramming examples -- and even those
have largely been fixed -- there's no way you could even measure this, let
alone justify such a strong, broad opinion. You're using incomplete
information to justify sloppy engineering and promoting it to others.

~~~
Arzh
It's compile times, those are very easily tested and measured.

~~~
tacos
Templatizing/de-templatizing enough code to see a difference would be a
significant effort on any non-trivial code base. But I'll spare you the
trouble: instantiating a template is less work than parsing a duplicated file.
Some of the early C++ compilers had problems but it hasn't been an issue in
20+ years. If you look at both the G++ and Clang test suites you'll see they
verify performance, memory usage and correctness with complicated templates by
doing basically this exercise for you.

~~~
Arzh
ok, thank

------
bigdubs
After watching Rob Pike's Go Proverbs talk I am pretty convinced generics, as
much as some would want it, will never happen. He proselytizes "just copy a
little code here and there" quite clearly, which is at odds with the
complexity that generics would add.

~~~
ktamura
This. For better and for worse, Go was designed for "simplicity", and generics
are anything but simple. I'd be very, very surprised if Go thinks about
generics in earnest anytime soon.

I don't say this in anyway to eulogize Go: In some ways, Go is pathetically
unexpressive. That said, it currently fills that gap for writing middleware
between C sacrificing too much developer productivity and Perl/Python/Ruby/PHP
sacrificing too much performance. Generics would be nice to have for this core
use case for Go, but it's probably not critical.

~~~
catfest
I don't see why you'd choose Go instead of a JVM language like Java, you get
the language simplicity (plus features like Generics) and the performance
upside too.

~~~
omginternets
>you get the language simplicity

And the most complex toolchain imaginable. This is what turns me off to Java,
personally, but I think my case is fairly representative.

~~~
sievebrain
If popular Java toolchains are the most complex you can imagine, I assume you
have never encountered autotools, or really any toolchain for a large C++
project.

Toolchains normally mean build systems, debuggers, profilers, editors and
other things.

Java itself doesn't require any build tool at all, you could do it all with a
custom shell script. The next step up after that is an IDE like IntelliJ where
you press "new project" and just start writing code. The IDE's build system
will do it all for you. There is no complexity.

But most people want features like dependency management, IDE independence,
command line builds, ability to customise the build with extra steps and so
on. That's when you upgrade to something like Gradle (or maybe Maven if you
like declarative XML). That'll give you dependency resolution with one-line-
one-dependency, versioning, automatic downloads, update checking and other
useful features. Many IDEs can create a Gradle project for you.

When I first encountered Java it seemed the most popular build tool was Maven,
which looked very over complex at first due to its poor docs and love of
inventing new words, but pretty quickly found that it wasn't so bad in
reality. Gradle avoids the custom dictionary and uses a much lighter weight
syntax. It's pretty good.

~~~
stcredzero
_The IDE 's build system will do it all for you. There is no complexity._

~~~
krakensden
The siren song of just-one-more-layer.

~~~
sievebrain
I don't see your point. If you have a collection of source files, then
_something_ must search the directory tree to find them and feed them to the
compiler ... ideally, only the files that have changed, to give fast
incremental compilation.

If you use a typical Java IDE like IntelliJ then the program that does that
will be the IDE. There is no "one more layer" because that's the first and
only layer.

If the IDE build system does not provide enough features or you'd like your
codebase to be IDE independent, you can also use a separate build tool, or a
combination of both (in which case the IDE will sync itself to the other build
tool).

In that case there are two layers. But Go does not have any magical solution
to that. There will be Go apps that need more than the little command line
tool can do as well.

~~~
omginternets
>typical Java IDE like IntelliJ

So now I need to change my text editor?

~~~
sievebrain
No. If you want to use vim then you would just use Gradle or Maven as your
build system, instead of Make.

~~~
omginternets
Right, so then it _is_ more complex than `go build`. QED.

To be clear, I'm not claiming that Go is "better"; I'm just pointing out that
this is why one would chose Go over Java. Sometimes this particular benefit
doesn't outweigh the costs relative to developing in Java, but
language/toolchain simplicity remains -- nonetheless -- the reason why people
prefer one over the other.

~~~
sievebrain
Huh, no, it isn't.

Yes, "gradle build" wants to see a "build.gradle" file in the current
directory, but you can run "gradle init" to get one. And after that everything
except specifying dependencies is by convention.

There's really little to no difference in complexity here. What Go saves by
not having a build file it loses by not encoding enough information about
dependencies in the source, which leads to horrible hacks like vendoring.

------
Animats
Generics as a language retrofit tend to be ugly. See C++.

I was at one time plugging for parameterized types. Go already has
parameterized types; "map" and "chan" are parameterized types. You write
"make(chan int)" and "make(map[string] int)". You just can't define new
parameterized types; "map" and "chan" are all you get. With parameterized
types, you could create more generic data structures; if you needed a generic
b-tree or a quadtree library, you could have one. Maps in Go are more special
than they should be.

Parameterized types are less powerful than generics, but not too far from what
Go now has. The goals in the document mentioned here require generics with all
the bells and whistles. Remember, Go still has reflection; if you don't need
high performance, you can simulate generics at runtime.

~~~
Ericson2314
Reflection comes without the compile time guarantees (parametric polymorphism
offers), and that is a far greater loss than the missed performance
opportunities.

------
f2f
"The intent is not to add generics to Go at this time, but rather to show
people what a complete proposal would look like. We hope this will be of help
to anyone proposing similar language changes in the future."

This started in 2010. Hopefully an illustration that go's developers are not
against generics in general, this ought to quell some of the negativity...
Pick one of the four proposals you like :)

~~~
andrewstuart2
The proposal document itself may have existed for that long, but it's only
been public for 14 days. To me, the important portion is the link to the
discussion issue [1] created 2 hours ago, which to me seems like a more
significant step towards doing the actual work.

Before, the default response was "we're thinking about it." Now, it's "let's
all talk about it."

[1]
[https://github.com/golang/go/issues/15292](https://github.com/golang/go/issues/15292)

~~~
f2f
but the existence of the proposals assumes there were internal discussions,
which is counter to the argument that go devs don't care about generics. had
anything good come out of that it would've been published in the open. as it
stands, the negatives outweigh the positives. hopefully the new discussion
will change that, or an entirely new proposal will make everyone see the
light.

~~~
kyrra
This was actually mentioned during the Golang team's AMA on reddit. They have
wanted to make the proposals for generics public for a while, it probably just
took some effort to organize it all and make sure it was OK to publish.

[https://www.reddit.com/r/golang/comments/46bd5h/ama_we_are_t...](https://www.reddit.com/r/golang/comments/46bd5h/ama_we_are_the_go_contributors_ask_us_anything/d03tsxw)

> Some people on the Go team have sunk considerable time in producing generics
> proposals, but they've all had serious drawbacks. I'm hoping those proposals
> will be published at some point so people can see the depth of complexity
> that generics bring; it's almost always underestimated.

------
teps
What people think of generic package instead of fine grained generics?
[https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX...](https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-
HnNjkMEgyAHX4N4/edit#heading=h.wko1dvdznk4y)

I think they would really fit the language well. The good part is:

* Only the package and import statement change, the rest of your code stay the same and is not cluttered

* They are easier to reason about as it is more coarse grained

* They do not break the compatibility

The the bad part is:

* You cannot implement filter/map/reduce (but being able to implement them would conflict with the orthogonality of the language)

* It could lead to code bloat, but not more than manually copy pasting the code.

~~~
stcredzero
I like this idea. It would allay a lot of complaining.

------
coldtea
As long as programmers that are comfortable with (and prefer) 30+/40+ year old
PL paradigms are at the helm of Go's design, it's not very likely the language
will grow Generics.

To paraphrase Max Plank:

"A new language-level feature does not triumph by convincing its opponents and
making them see the light, but rather because its opponents eventually die,
and a new generation grows up that is familiar with it."

~~~
fauigerzigerk
Only Max Planck was talking about questions of truth.

~~~
coldtea
That's why I said I'm paraphrasing him.

That said, he talked about questions of physics, not "truth".

Now, those new theories might or might not be truth.

But the fact that (in his phrasing) they only prevail not because of extra
proof, convincing etc., but just because a generation that didn't like them
died, doesn't make them seem particularly "truth" based.

Mostly "generational-fashion" based.

It could of course be that the new generation of physicists is also more
capable to accept the truth (and Plank might believed that), but this doesn't
derive directly from the statement.

The statement only goes as far to say that new generations of physicists are
more capable to accept newer theories (the ones that grew with them, and they
are more familiar with them than the oldsters are).

~~~
fauigerzigerk
_> That's why I said I'm paraphrasing him._

I suppose you paraphrased him to draw an analogy. And you did it by replacing
"scientific truth" by "language level feature".

 _> That said, he talked about questions of physics, not "truth"_

Here's what he said:

 _A scientific truth does not triumph by convincing its opponents and making
them see the light, but rather because its opponents eventually die and a new
generation grows up that is familiar with it._

Similarily, proponents of generics like to portray the creators of Go as the
old guard that is in denial of an indisputable scientific truth.

But whether or not the added expressivity of generics is worth the added
complexity they introduce into a language is a matter for debate dependent on
context, not a settled scientifc question.

~~~
coldtea
> _Similarily, proponents of generics like to portray the creators of Go as
> the old guard that is in denial of an indisputable scientific truth._

Well, they are the old guard (both in age and in adopting 30+ years of PL
research).

And it is an indisputable truth that Generics are both safer and/or faster
than the workarounds (copypasta, interface{}).

> _But whether or not the added expressivity of generics is worth the added
> complexity they introduce into a language is a matter for debate dependent
> on context, not a settled scientifc question._

I don't think we do/should consider generics complex anymore. Even Java
programmers, the most tame of the bunch, got along with them just fine for a
decade now.

Besides, Go has closures and channels, two things that seemed alien just 1-2
decades ago to enterprise programmers. Surely generics, an even older and more
widespread concept is not that foreign...

Besides, Go already has generics -- it just doesn't allow the programmer to
use them too.

------
insulanian
My code is full of map, filter, reduce/fold and similar generic reusable
functions.

How do people deal with such things in Go? Do they really make copies of such
functions for every type they're working with? (And by type I don't mean just
int/string, but all model entities/classes.)

~~~
NateDad
map and filter are often just syntactic sugar for a loop, so I just write a
loop.

I work on a ~1M LOC codebase in Go and it's really not a problem. map and
filter would not make my life significantly easier. They're solving easy
problems.

Sure, I have some of this style code:

    
    
        var names []string
        for _, m := range machines {
            names = append(names, m.Name)
        }
    

But, really, is that so much worse than this?

    
    
        names = [m.Name for m in machines]
    

Sure, it's spread across a few more lines, but line returns don't cost extra
money... and if you decide you want to later do something more inside the loop
for each machine (default the name, cache the ID, etc), you can do that
trivially by adding lines inside the loop.

This code is not hard code to write. If you're used to just being able to slap
out map/filter etc in a single line, I could see how it could be annoying...
but it's easy, just write it. There are far more difficult things to figure
out in our jobs, why worry about the easy stuff?

~~~
dominotw
>> But, really, is that so much worse than this? names = [m.Name for m in
machines]

You can take that code and interpret that as database query, like C# LINQ.

you frist example is 'how' vs 'what' of second example. Once you stop telling
the computer how to do things and just tell it what you want all kinds of
things become possible.

~~~
NateDad
But then you have no idea what the computer is actually _doing_. There's a big
performance difference between an in-memory loop and querying a database. This
is one of the things I like about Go... what the computer actually does in
response to any random line of code is pretty obvious (except for function
calls, which of course can do anything). When you hide away the loop inside a
map statement, you get people doing dumb things like this:

    
    
        names = [m.Name for m in machines]
        ids = [m.ID for m in machines]
        addrs = [m.Address for m in machines]
    

So now we're iterating of over the list of machines 3 times... or making 3
database queries or whatever.

~~~
dominotw
>But then you have no idea what the computer is actually doing.

You trust it the same way you trust go compiler to do the right thing when you
give it code to compile.

~~~
NateDad
That's the nice thing about Go code... I almost always know exactly what it'll
make the computer do. I know how much memory will get allocated, what the
likely CPU usage is going to be, etc. The abstraction between the code and the
computer is low, which helps lets a lot in understanding why your code is
slow, or why it's producing a lot of garbage. "oh hey, here's a loop in a
loop... oops, N^2 time".

------
golergka
Lack of generics was one of the reasons I abandoned Go halfway through a hobby
project (the other reason was lack of normal exceptions).

But. Go's principle is simplicity and understanding the concepts you're
working with. And generics as a concept is a little bit more complex than
simple List<int> explanation leads you believe. As C# developer (language with
very good generics support), most of other C# developers I've met,
unfortunately, can not easily and confidently explain covariance and
contravariance concepts in an interview setting — which means that they don't
understand generics concept completely. Mix it up with "null" virtual type,
and you've got yourself a type system that you think you understand, but
really don't, and will discover this misunderstanding in the worst possible
moment.

So, while Go sucks for projects that I personally usually work on, its
qualities make it a great language for other kinds of projects, and for these
projects, generics may not be wort it with a trade off with simplicity.

------
dom96
Maybe instead of adding generics to Go it's time to look into alternative
programming languages which already implement generics, like for example Nim.

~~~
idobai
You forgot that most of golangers are ex-php programmers and students with no
experience. Just look at what they're talking about: they think generics are
the opposite of simplicity and can make performance and compilation time
worse. Meanwhile, Nim has generics with other useful features and has faster
compilation time along with better optimization. If google would put 'goto'
into go golangers would still use it anyway.

I've tried go a few times and it was full with repetition and boilerplate -
felt like java 1.0. It seems like new coders like to repeat themselves more
often than learn how to use proven concepts.

~~~
treehau5
> You forgot that most of golangers are ex-php programmers and students with
> no experience.

How hopelessly smug and incorrect.

~~~
serge2k
It's a conversation about go, isn't being smug and/or incorrect fundamental to
participating?

------
rebnoob
"Let the machine do the work." [1]

By Rob Pike, a man of contradictions.

[1] [https://blog.golang.org/generate](https://blog.golang.org/generate)

------
chmike
Consider using the D language instead if generics is a problem. Go is what it
is and shouldn't change. It has it's advantages that make it optimal for
particular contexts. Otherwise you'll turn it into another c++. There is a
strong benefit in keeping Go simple as it is.

------
willvarfar
I would be happy if there was a generics solution aimed just at type-safety
for containers, and not a general 'reuuse' thing.

~~~
Ericson2314
You can easily have type parameters in data type definitions but not
expressions, but that wouldn't by much for containers.

------
tssuser
Let me give a concrete example of how I've been personally impacted by the
lack of generics. My project makes liberal use of pointers to represent
"optional" fields, since they need to be distinguished from the zero-type.
Alternatives would be to have a boolean associated with every field, but that
clutters the API and still faces a lot of the problems with using pointrs,
such as:

\- Easy to forget to check that pointer != nil

\- Overloaded semantics: it's unclear whether a pointer represents an optional
type, or is being used to pass-by-refrence (i.e. unclear whether a value
should be treated read-only)

\- Need to deep copy every struct, which is easy to forget and inefficient (at
least the reflect version)

There are solutions to each of these points, but they all add complexity (e.g.
generating code), and most take a lot of extra effort. With generics I could
have Optional<T>, With a Get() function returning 2 values: the value type,
and present (i.e. the way maps work). The caller is forced to handle both
returns, making it much harder to forget to check it.

A lot of arguments for generics focus on higher-level functional programming
abstractions, but this is a simple and extremely common use-case, and the lack
of a solution is responsible for many real-world bugs.

~~~
sacado2

        type Optional struct {
            stuff interface{}
            present bool
        }
        
        func (o Optional) Get() (interface{}, bool) {
            return o.stuff, o.present
        }
    
        func NewOptional(stuff interface{}) {
            return Optional(stuff, true)
        }

------
plq
There was a time when the only language with decent platform support _had_ to
have turing-complete meta-programming support, inheritance, polymorphism,
lambdas, preprocessor, custom allocators, placement new, std::erase_if, etc,
etc. because we were basically stuck with it.

Those times are now way behind us. Today, there is a plethora of languages to
choose from, each with their strengths and weaknesses, each most powerful in
the niche it's designed for.

Go is not a language with generics. If you need generics, don't use Go.

Go should not have generics unless it's trying to dominate the world. And we
all know that no language can achieve world domination nowadays, not anymore.
So it should rather trying to be the best language possible in the niche it
was designed for. That niche doesn't need generics. On the contrary, a vocal
part of the community says generics would taint Go.

Go doesn't have generics. It's however got a proper FFI. Use it. Or don't.

------
tombert
Isn't a huge issue with generics the compilation time?

Much as I love Haskell, I'm not going to sit here and tell you that a big
program compiles quickly.

That might be an individual issue with Haskell, but regardless, isn't type-
inference kind of expensive in compilation-land? And wouldn't that kind of
kill one of the big features of Go?

~~~
parenthephobia
Type inference isn't synonymous with generics, and it isn't necessarily
expensive. It depends exactly how much you leave up to the compiler.

Some very strong kind of type inference are undecidable _in general_ and can
be very expensive to compute when there is an answer.

But you might bear in mind that almost all static compilers, including Go,
already determine the types of arguments to functions so they can complain if
you're passing the wrong type. Comparing that against a set of functions isn't
much of a stretch, especially if the type matching rules were pretty strict,
as they normally are in Go.

Not all generics are generic functions, anyway. A more limited, but still
potentially useful, form of generics is generic packages. Generic packages
have type parameters, whilst inside the package refer to the specific concrete
type the package is being instantiated for.

A hypothetical sort package might have a single parameter denoting the element
type it sorts. Conceivably it could be defined as

    
    
        package sort(T)
    
        func Sort (a []T) ...
    

imported as

    
    
        import isort "generic/sort" (int)
    

and then used as isort.Sort.

~~~
tombert
Admittedly I've never implemented a compiler, or a type system, so I was just
speaking out of my behind to an extent, but your explanation makes sense.

------
acjohnson55
At this point, I have to just conclude that Go isn't "for me". I respect the
great things the community has produced. But I'm just not interested in a
static language without generics.

------
jgalt212
As an outsider, I've been following Go for a while, and given the lack of
common high productive language features such as Generics and optional
function arguments with default values, to me, it seems like right now Go is
much better than C, and in some dimensions better than Java and in others
worse.

If it just adds a few things, and then when you account for portability and
speed, it could be better than the dynamic languages that people often compare
it to.

------
agentgt
I have some biased doubts (come from the JVM world) about needing really fast
compiling and is often cited as the reason Go does things the way it does (or
is).

Is binary dependency management just not an option ever?

I have a friend that works for Google and supposedly they have a proprietary
build infrastructure that will offload the building of C++ code into a
cluster. I sort of wish Google open sourced that as I believe it basically
does some form of binary dependency management.

Yes I know Go like C++ can target lots of platform (and thus needs many
binaries built) but an organization only needs the major ones. And yes I know
the language statically compiles to a single binary but that doesn't mean
things can't be precompiled.

Go these days seems to be mainly used for microservices or small utilities and
thus you don't need and should not have a gigantic code base for such things.
I can understand monolithic UI apps having large code bases but this is
clearly not what Go is being used for these days.

There are many other languages that compile to native that seem to compile
fairly fast (OCaml and Rust from my experience but I don't have huge code
bases).

Is compilation speed really an issue given the use cases for Go?

~~~
MustardTiger
>Is compilation speed really an issue given the use cases for Go?

Yes, I find compilation speed to be one of the most important things. But it
is not a selling point for go. The go compiler is not very fast, and speed is
not an acceptable excuse for a lack of parametric polymorphism. Ocaml has not
just parametric polymorphism, but many other basic type system features. And
yet ocamlopt is both 5-10 times faster than the go compiler, and still
produces faster binaries.

~~~
agentgt
That is what I'm saying (I think we agree). It seems like a focus of Go's
simplicity is to improve compilation speed and yet there are languages like
Ocaml that do have generics (and a whole lot more) that seem to compile
faster.

------
isuckatcoding
This makes me wonder if this has happened before in another language. I can
totally imagine 10 years ago someone saying "oh we'll never need that in PHP"
and voila 10 years later you've now got feature X in PHP. Any of you wise old
timers want to share such examples? Does history keep repeating itself with
these sorts of things?

~~~
kqr
Generics in Java? Anonymous functions in Java? Most everything in Java?

~~~
isuckatcoding
I guess I was think of the community mentality and how it evolves as well.

------
slantedview
From the post:

> As Russ pointed out, generics are a trade off between programmer time,
> compilation time, and execution time

This misses the most important metric: quality. Lack of generics forces
copying and pasting of code which inevitably lowers quality and increases
defects. It's amazing to me that with the all the expense that crappy software
causes, we're more focused on compilation and execution time. Last time I
checked Golang's performance numbers, the supposed benefits of this focus were
not present while the downsides of being a language that forces programmers to
do the wrong thing were present as well.

~~~
Gibbon1
I often get crap when I mention most of the time execution speed is just not
important.

However it is important vastly more important for google than me or you.
Simply because google and a lot of other web companies are running on such
tight margins.

Consider my company is paying maybe $200/mo for AWS. When we are doing half a
million a month in business. Each cpu cycle for us represents a lot more
revenue for us than google is making. The flip side is programmer time matters
a lot more to you and me than to google.

------
ungzd
Proposal: Algol should have dependent types.

------
musha68k
The one thing that makes Go special is that it's pure "Engineering-Zen".

While that doesn't make programming in Go the most _fun_ exercise it makes it
a profound one (after some getting used to).

Less distractions, less eGo (forgive the pun).

Disclaimer:

I'm still having a hard time embracing all of that myself - I don't even
_like_ Go.

I _really_ miss all the functional cleverness I've come to get used to over
the years - especially talking Erlang/OTP as the main (losing) "competitor"
for most of my backend projects here (microservices, kubernetes yaddayadda).

~~~
a-saleh
How do you cope?

Weirdly enough I started my career writing selenium test in clojure and got
used to (reduce (map (filter ... way of doing things.

Then we moved to python and still I was at least able to do (modified(x) for x
in xs where satisfies(x))

Then I needed to do some C# work and I really liked LINQ.

Now I work in javascript and still can at least
_.chain(thing).map().filter().value()

It seems that we will use Go for some things, and as far as I know, I am back
to using for cycles.

~~~
musha68k
Hi there, I feel you :)

The way I've coped with this so far is to embrace it and just work through the
given task - less warm-fuzzy-feeling and more "manual work" and time needed
for sure but it wasn't that big a deal once I just let "go"...

Not having list comprehensions definitely is one of those things which makes
me feel more like a "stupid coding monkey" but again you can be productive
with less elegant tooling as well...

~~~
a-saleh
Well, we shall see how this will end up :)

If everything we would do are just simple micro-services, I think I would
actually kind-of enjoy it.

------
bsaul
Could anyone here tell me why, in practice, it isn't possible to write generic
algorithms such as sorting or Red/Black T using interfaces only in GO ? It
seems like having interfaces such as "comparable, equatable,etc" should work
in theory.

I've read somewhere that it was memory usage related, but i've got trouble
picturing why (maybe an example would help)

------
meapix
Can you give an example of the issue you're trying to solve with Generics and
Go is giving you hard time? don't take Go to C++.

------
dschiptsov
Go is supposed to be a better C, not a better C++.

~~~
loup-vaillant
A "better C" with garbage collection by default? C and Go are in different
categories. They fill different niches.

~~~
dschiptsov
The main designers of Go (originally from Bell Labs) might think otherwise.

------
kzhahou
Came for a Proposal. This article only provides _motivation_ for generics.

Are there any concrete proposals on the table? I don't recall seeing any, and
it would be great to work from that and pick it apart. Otherwise, we're just
arguing the opinion that they're useful, against the opinion that they'd soil
the language.

~~~
enneff
Yes, there are four at the bottom of the doc.

~~~
kzhahou
Wow, major props to him for having written four proposals!! Still, he says
they're all flawed so far...

------
sambeau
If it was up to me I would break with ASCII for the syntax. It would make
parsing easier for the compiler while simultaneously making it slightly
annoying to use for the programmer.

Having to reach for a complex key combination would be enough to remind
everyone that Generics should be used sparingly.

------
ngrilly
The four proposals linked at the bottom of the page are very interesting, and
prove that a lot of work have already been invested in bringing generics to
Go. It makes me confident that it will happen one day, when the pieces fit
together in a nice way.

------
amhunt
Sitting in a lecture by Kernighan rn and he says GO will NOT be implementing
generics

------
andrewfromx
can I tell u the BEST thing about golang? Strings cannot be nil! It's amazing.
They are always "" or you know, "something" so you never have to test for if s
== nil || s == "" or in ruby s.blank? to cover both cases. that is all.

~~~
kdogt
In sane languages (see: Haskell, Swift, Rust), this is the case for _all
types_. Having non-nullability only be the case for one type might be worse
than having everything nullable, actually.

------
kafeltz
Rich Hickey could play on golang, this guy is so fascinated by simplicity too.

------
amelius
How does Erlang solve it?

~~~
pmarin
Dinamic languages don't need generics

~~~
brndn
Can you explain?

~~~
nostrademons
The point of generics is so that you can use the same code with many different
types. With dynamic typing, you can use the same code with anything, it just
complains at runtime if you call an operation that isn't supported on a
particular type. It's like every operation is implicitly generic.

You could look at generics as a way to bring some of the flexibility of
dynamic languages to a static type system, so you get the expressivity
benefits without sacrificing type-safety.

------
AzzieElbab
If you google "brutally practical" you will get "uninspired hack". Either that
or the whole thing is simply pre-alpha

------
elcct
One day someone will create a fork and implement it.

------
max_
just fork the repo.

------
xiaopingguo
Why not just fork the language? Why does one language need to do all the
things?

~~~
duaneb
Generics are not "all the things". Last i checked there was still no object
inheritance (in a subtype sense for interface implementations), no operator
overloading, no bytecode/vm/jit, no inline asm, no macros, no pluggable gc, no
call/cc, no (idiomatic) exceptions, no currying, no weak typing or implicit
conversions, no way of enforcing referential transparency, no STM, no
laziness, no assertions, no contracts, no untagged unions, no algebraic data
types, no covariant return types, no pattern matching, no method overloading,
no simd, no decorations/annotations.... I am sure i missed a lot.

EDIT: of course this is good; such a language would be beyond nightmarish. By
which i mean c++ or scala.

~~~
ViktorasM
but having all those things go would become another C++ with a different
syntax.

I like the direction Go is going of "there are no options to choose", like
unconfigurable fmt, or the fact that there is no way to create "exotic"
implementations.

However, generics would be my number #1 on the list of "maybe let's add that".
Would be nice to have less "interface {}" in reusable libraries.

Exceptions would be probably second, but that would come with some sort of
runtime cost. With them Go would start to drift towards "generic programming
language".

~~~
coldtea
> _but having all those things go would become another C++ with a different
> syntax._

Haskell and CL have "all those things" and they are not "C++ with a different
syntax".

I don't know why people repeat these cliches... It's not like a language can't
have many features and be designed well at the same time. It just takes
preparation and effort instead of ad-hoc additions (like with C++).

~~~
geodel
But then there need not be raging debate about Go/Generics. As pragmatic
developers can move to Haskell etc if Go has no value add to them.

~~~
coldtea
That reminds me of the "If those books say something worthwhile, it will be in
the Kuran, too, so it's ok to burn them. If they don't, they it's ok to burn
them anyway" argument -- something a sultan is alleged to have said as the
justification for burning the library of Alexandria.

The thing is, it's not just the feature set, different languages have lots of
different things going (or not going) for them too.

One might like Go's syntax over Haskell's.

Another might not like Haskell's purity.

A third might not like Haskell's heavyweight platform installation and
tooling.

Another might be forced to use Go because of his work but still hate the lack
of Generics.

Yet another might prefer Go over Haskell just for the fact that you can find
Go jobs, where Haskell jobs are too few and far between.

------
peteretep
If they accept generics, then there is an implication that the language design
isn't infallible as a result of being written by Rob Pike, and then the whole
house of cards falls down as people start clamouring for things like real
exceptions.

~~~
enneff
Your comment does a great disservice to Robert Griesemer, Ken Thompson, and
the many others who contributed to Go's design.

~~~
nostrademons
Not to mention Ian Lance Taylor, who's been on the Go team since before it was
public, authored the GCC Go frontend, was de-facto leading the team when I
left Google in 2014, and also happens to be the author of the proposal.

------
mk44
Go is designed by google, for google. Why should they make it to your liking?
Why do you rely on google?

~~~
eru
Similar things can be said for C and Java, and many other languages.

------
thegenius2000
I agree with the author's request, I'm just not convinced he proposes a
design. I mean I recognize see the need for some sort of generic programming,
but the big question is _how_ not why, right?

Edit: My bad. Didn't see the bottom of the page.

~~~
wrs
He's proposed _four_ designs so far. See the bottom of the page.

