
Summary of Go Generics Discussions - scapbi
https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/edit?pli=1
======
commentzorro
This is such a biased document as to be pointless. The authors are so opposed
to generics that I don't understand why they bother. Just a few beauties:

 _> The generic dilemma is this: do you want slow programmers, slow compilers
and bloated binaries, or slow execution times?_

I don't think these are the only outcomes, but lets go with it. A slightly
slower compiler then. Solved.

 _> The generic structures are less useful than a concrete one._

If they weren't more useful then nobody would be arguing for them.

 _> Generic structures can be less optimized than a concrete solution_

Ridiculous.

 _> Code won’t look idiomatic._

Idiomatic is a function of the language syntax and features. If generics are a
feature then their use will, by definition, be idiomatic.

And on and on. At this point people using Go accept the lack of generics (and,
oddly, sometimes wear the omission as a badge of honor). I don't think anyone
happily using Go is expecting generics anytime soon, if at all. And I don't
think the authors need a paper to show their dislike for them. Who are they
trying to convince anyway?

EDIT: A few folks have told me I come across too heavy handed in my reply. I
apologize to and don't mean to discourage the author(s)! It's a tough document
to write. Especially if this was just a starting "brain dump." The document
title had just set my expectation towards a neutral tone.

~~~
pdpi
> I don't think these are the only outcomes, but lets go with it. A slightly
> slower compiler then. Solved.

Except that a capital-F Fast compiler is a design goal for the language, so
that's the _least_ desirable of the three. I feel tempted to go with slower
execution times, simply because it's already a part of the design as well: you
can't optimise too aggressively on a limited compilation time budget.

~~~
ascotan
Generics are a nice feature to avoid code duplication. However, they are not
required to be used in every application. Whatever the solution is, it should
not affect code that doesn't require the use of generics. If the entire
language is affected (such as a slower runtime because of the need to
box/unbox) that would be a step down.

~~~
frowaway001
So how are you writing Go if you neither use arrays/slices, maps, channels,
etc.?

------
simias
> No abstract examples/arguments. These cause the discussion to lose focus and
> make examples harder to follow. The example/argument must be traceable to a
> real-world problem - Go is intended to solve real problems not imaginary
> ones.

I find that's a very good rule in those discussions, it's too easy to get
bogged down to some obscure use case and miss the forest for the trees.

I note however that the authors seemed to have forgotten about that rule just
after writing it down since the rest of the document is full of vague
assertions and unsubstantiated arguments like:

\- "I have heard of simple libraries having text segments shrink from
megabytes to tens of kilobytes by revising or eliminating the use of
templates."

\- "Generic algorithms can be harder to follow than their non-generic
counterparts."

\- "Fancy algorithms are slow when n is small, and n is usually small. - Rob
Pike"

\- "map/slice suffice for most of the cases encountered in programming. (based
on some community opinions [https://groups.google.com/d/msg/golang-
nuts/smT_0BhHfBs/MWwG...](https://groups.google.com/d/msg/golang-
nuts/smT_0BhHfBs/MWwGlB-n40kJ\)"). The linked thread contains a bunch of
posts, not sure what I should be looking for (I thought the whole point of
this document was to "go over the relevant points without digging through
hundreds of forum posts"?)

\- "Code won’t look idiomatic." I'm not sure what that even means.

I don't know if generics have a place in Go or not but I'm not sure this
document is going to help solve that issue. Making a list of concrete use
cases for generics and discussing possible alternatives would probably be more
constructive.

~~~
jerf
"I note however that the authors seemed to have forgotten about that rule just
after writing it down..."

I feel I need to remind you, and a lot of the other commenters here, that this
is a top-level _summary_ of all the various arguments. And that it is possible
on the Internet to _mention_ arguments without actually _advocating_ for them
at the same time. I doubt you could find any individual on the planet that
would "agree" with that entire document from top to bottom.

~~~
simias
Then it should link to the various places where those arguments have been
discussed. As it is it's hard to take that as a neutral reference and looks
more like an opinion piece against the implementation of generics in Go trying
to pass off as a neutral reference. If that was on wikipedia it would be
littered with [citation needed].

------
diakritikal
Previous discussion:
[https://news.ycombinator.com/item?id=8756683](https://news.ycombinator.com/item?id=8756683)

------
datashovel
Something that has turned into such a contentious topic one would think
someone would fork the project to add generics themselves. Perhaps in an
effort to "prove" how it could be done easily or cleanly.

How many man-hours have been spent arguing about this?

~~~
jerf
I've actually considered stabbing at it, but at the moment it's best to wait
for the idiomatic Go rewrite of the compiler to get further along.

And by "stabbing at it" I mean opening up the compiler to see how difficult it
would be, not a commitment. But even for that, the best answer right now is to
wait for the in-progress compiler rewrite to get further along.

~~~
datashovel
I think it will be interesting to see what kinds of things bloom from the
rewrite of the compiler.

------
dale-cooper
From the java section:

> A vector of bytes uses significantly more than one byte per byte.

There is still the option to use an array of bytes (the primitive data type,
not the class Byte) if the performance of boxing/unboxing is a problem.

In fact, i don't understand how the vector example is relevant to generics at
all. Even pre-generics the underlying storage for a Vector in java would be an
Object array so the boxing/unboxing would still happen?

~~~
jerf
Ah, this threw me for a while too. So the answer appears to be: Suppose you
have a generic function X(Y), where the "Y" is generic. Now suppose you want Y
to be truly _generic_ , and not just Java-style generic, which means that Y
may be any size. That is, it may be a "byte", it may be "short", a "long", a
184-byte struct, a pointer, etc etc etc. The way most programming languages do
functions, functions encode into themselves the sizes of what they are
expecting, and the expectation for how they are going to receive parameters.
Therefore, a single function can't take all those options, and at the very
least you end up needing one per base size, plus one for spilling to the
stack... and that's _just_ to deal with the size issue, you still have
signedness, various struct properties if you're passing structs, etc.

So one option is to "box" everything, which basically amounts to saying "I
will take a pointer to everything", and in the case of Go, "I will take the
pointer to that thing's type". (That's how interfaces work in Go.) Now
everything is the same size (pointer-sized). But now everything's boxed.
Alternatively, you can compile lots of functions, but now everything's
compiled in separate copies of the function.

From the high-level language POV it all seems so simple. When converting it
into actual assembly, which has to interact with the rest of the system, it
gets more complicated, and the performance implications of even slight
slowdowns to a function call can be catastrophic given how many of them we
make.

Personally I'm still interested in the question of whether it's feasible to
create a different calling convention into a generic function that deals with
this directly. This might not be possible in C due to its age, or C++ due to
its reverse-compatibility heritage, but I'm interested in whether we can write
a sufficiently-generic (in the more general sense of the term) function
calling system that it can work with Go better. Basically looking at types
like a vtable and abstracting out all the calls that are size-dependent into
vtable-lookups, which ought to be slower but only _slightly_ slower than a
direct call (given that it seems like everything can be resolved at compile
time except the actual address). But I don't know. Interested to hear if
anybody else has ever tried that or anything similar. (Assembler is a great
deal more flexible than the structured programming we have laid on top of it,
at least in theory.)

~~~
dale-cooper
Thank you, that was a great explanation.

For what i've been using java for it's never really bothered me. When there is
need to use primitives it's almost always in the form of a list where you can
just use an array instead to avoid the boxing/unboxing.

The risk of null pointer exceptions when implicitly unboxing objects are more
annoying..

------
robteix
The Go team has repeatedly stated they have nothing against generics per se
and they see a value for it. They simply have not found an implementation that
works with language values (simplicity, fast compilation, etc.)

If anyone can come up with an implementation that works, I see no reason why
the team would say no to its inclusion.

------
bsaul
/offtopic

This kind of discussion is actually something that bothers me even more than
generics at the moment : [https://groups.google.com/forum/#!topic/golang-
nuts/m7k9Epxq...](https://groups.google.com/forum/#!topic/golang-
nuts/m7k9EpxqK4I)

Come on... removing an item from a list requires tricks ?? I know go aims at
being memory efficient, but delete(list,obj) should be idiomatic.

~~~
scott_s
I'm not a Go programmer, but I think this is a problem of data structure
expectations. Slices are not "lists", but views into arrays. So, by design,
slices are a view into contiguous chunks of values. In such structures,
removing an item will necessarily be O(n).

A general principle in interface design for data structures is don't make
expensive things easy. So, if removal from a slice is O(n), then the data
structure is obviously not optimized for that, so don't provide a function for
it.

~~~
bsaul
I would agree, except for the fact that slices have a lot of very convenient
sugar syntax, making it look like the de facto standard for storing anything
(with maps that is).

Well, i may be spoiled, but ever since i stopped working with C, i never had
to deal with data structure so different between arrays and list than go (that
is, slices and container/list).

The performance concern is an absolute hypocrisies. Whenever you decide which
structure you pick in eg, Java, you know that the various containers are
optimized for various operation, and you decide which to use depending on
performance only.

In go the language is so broken (because of the type system) that using a
chained list vs an array makes your code look completely different.

------
callesgg
That generics would allow for better Type-safety is only true if one compares
it to using empty interfaces (or some other type less thing).

But it would actually lead to less accurate Type-safety than if one had a
different sort method for each sortable type, it would lead to some amount of
"duplicated" code but that is a different matter than Type-Safty.

~~~
tel
It would lead to less safety but _more_ type safety, actually.

[http://jspha.com/posts/six_points_about_type_safety/](http://jspha.com/posts/six_points_about_type_safety/)

------
Pxtl
It is incorrect to say that the c approach is no generics. C has its
precompiler macros which functionally provide a crude form of generics.

~~~
wheaties
C macros are the worst form of macros. They are string substitution without
type checking and can very easily leaf to all sorts of issues. That said I'm
in the macros camp instead of generics just because I think go authors would
actually do it.

~~~
copsarebastards
If you're rooting for language features based on the willingness of your
language designers to implement them rather than what will make the language
better, your language ecosystem is fundamentally broken and it's time to move
on.

------
dvirsky
I wonder what a survey of real Go users about generics would show. I'm betting
an overwhelming majority would like that.

~~~
bsg75
Would these be people writing "production" code in Go who need generics, and
for some reason have not been instead using a language with the features they
need?

The whole continued argument is odd. The "whole generics are important" and
"Go is too simple" thing seems counterintuitive when all of the comments
mention Rust, Haskell, Java, etc., yet the proponents of generics are not
using those languages instead.

Why if Go does not have the features one needs, would a person be compelled to
use it?

~~~
dvirsky
Simple - it has many other virtues that outweigh this even if you need it.

I'm writing a lot of production Go code, and I'm very happy about the
language. I wouldn't put generics at the top of my wish list but at times I
wish I had them. But not enough that I'm willing to use a 3rd party solution,
so I guess not that much :)

