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

I'm sorry, but no: Generics are a technical issue and are not a political one. The Go team is not against generics per se, only against doing things that are not well understood and/or don't work well with Go.

There are deep technical issues that must be solved to fit the idea of generics into Go in a way that works well with the rest of the system, and we don't have solutions to those. I wrote on my blog about one issue years ago (http://research.swtch.com/generic), but there are others too. Even supposing you get past the problem on that page, the next thing you would run into is how to allow programmers to omit type annotations in a useful, easy-to-explain way. As an example, C++ lets you write make_pair(1, "foo") instead of make_pair<int, string>(1, "foo"), but the logic behind inferring the annotations takes pages and pages of specification, which doesn't make for a particularly understandable programming model, nor something the compiler can easily explain when things go wrong. And then there's a princess in another castle after that one I am sure.

We have spoken to a few true experts in Java generics and each of them has said roughly the same thing: be very careful, it's not as easy as it looks, and you're stuck with all the mistakes you make. As a demonstration, skim through most of http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.ht... and see how long before you start to think "was this really the best way to do this?" (For example, http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypePa..., but note that the latter page is only one part of the FAQ, not the entire FAQ.)

To be very clear, we acknowledge this fact: there are definite disadvantages to not having generics. You either use interface{} and give up compile-time checking or you write code generators and complicate your build process. But there are also definite disadvantages to generics as implemented in existing languages, and there is a very large advantage to not compromising today: it makes adopting a better solution tomorrow that much easier.

As I said in the interview at http://www.pl-enthusiast.net/2015/03/25/interview-with-gos-r...:

> Go is more an engineering project than a pure research project. Like most engineering, it is fundamentally conservative, using ideas that are proven and well understood and will work well together. The research literature’s influence comes mainly through experience with its application in earlier languages. For example, the experience with CSP applied in a handful of earlier languages—Promela, Squeak, Newsqueak, Alef, Limbo, even Concurrent ML—was just as crucial as Hoare’s original paper to bringing that idea to practice in Go. Programming language researchers are sometimes disappointed that Go hasn’t picked up more of the recent ideas from the literature, but those ideas simply haven’t had time to pass through the filter of practical experience.

I believe generics is one of those ideas. It certainly needs at least one more iteration, possibly a few more than that.

CSP is well understood because it's used in very minority languages, yet generics aren't despite being almost ubiquitous?

I understand the caution, but this justification doesn't add up.

The complexity in language theory does not stem from a single concept, but from their mix. If you take something like generics on its own, it is rather simple to add to a language. But once you mix it with other concepts, the complexity rises exponentially.

Generics + subtyping (inheritance) gives rise to a number of complex situations. Java needed to embrace bounded polymorphism in the type system in order to handle this. And we don't know about a simpler type system which is sound and has that particular mix. If you remove subtyping and replace it with another construct, type classes or implicits, then generics are somewhat easier to fit to the language.

CSP turns out to be far more orthogonal, as long as you use a typed channel primitive. Hence, it is easier to fit CSP into an existing model because its composition with other type theoretic constructs is far simpler.

The concept is ubiquitous. The specific design for each language is different, and what they all seem to have in common is that they require enormous complexity. See the rest of what I wrote.

Well, the fact is that many mainstream languages have Generics. You have an advantage to learn on others mistakes (e.g. made by those Java guys) and practice.

I understand that Go team are more "systems" persons rather than "languages" in general. Did you try to consult with Dart team? e.g. with Gilad Bracha. Maybe you should consider hiring some languages person in Go team.

It's just not an easy problem to solve. And I'm not convinced it has been already solved, much less solved correctly, in the vast majority of cases.

This is legal(-ish) C++:

template<typename T> T Add(T one, T two){ return one + two; }

It's completely illegal in C#. And Java. Both have "generics". Both are wildly different.

Then you have the Haskell camp which look at all of these "generics" and shake their heads and laugh bitterly since their static type system and "generic" blow all other ones out of the water anyway.

So when you say you want "generics" - which flavor do you want? How does it play with Go's interfaces? How deep down the rabbit hole do you go?

It's very easy, when you're not familiar with the problem to say "just do it" - but everyone seems to have their own idea of what "generics" is, how it works, how to constrain parameters, etc.

So even if the Go team picked an implementation from Camp A, I'm 120% positive that camps B, C, D, and X would declare it the worst implementation ever, and again, they've pleased no-one.

I'm glad they're sticking to their guns on this one.

Show them an implementation that works in Go, and they've said multiple times they might do it. Put up or shut up, basically.

I don't understand your logic - just because different languages have some differences in how generic compile-time type-safe code is written, Go should NOT have this at all? And the only reason is that some subgroup might not be fully pleased?

I'm a C++ engineer more than a decade now.. And I'll be more than happy if Go had ANY kind of generics - even Ada-like, with explicit instantiation... Anything is better than current interface{} run-time checked stuff.

Sounds like you have something in mind. All you have to do now, is:

1. Expand on your idea with some examples. 2. Show how this can be done without breaking existing Go code 3. Showing where the performance hits are - runtime? compile time? binary size? memory? 4. Show how this plays along with Go's implementation of interfaces, as well as other already-generic types, such as channels and maps.

If you can do all that, realistically, then I don't see why it wouldn't be taken seriously?

Heck, if you can provide even an example implementation (talk is increasingly cheap) I bet you'll get lots of people on-board!

You seem, like many others, to think that Go core team members don't want "generics". All they have ever said is - "we don't want bad generics". That's all.

Anyone can say "I don't know what exactly Go generics are, how they look like, how they perform, how they change the syntax, all I know is - I want them". Like I said, talk is cheap.

> Show them an implementation that works in Go, and they've said multiple times they might do it. Put up or shut up, basically.

Didn't someone fork Go and do exactly that only to get ignored? Perhaps it was a rumor, do you know? I'll see if I can find any reference to it.

That would be interesting to see. (I've never heard of such a thing...)

Best I could find was this:


It also led to a real world example where the author tried using Go for a project and had a lot of need for Generics:


Many members of the Go team have a background in languages, and are part of a greater community of software practitioners involved with language design. Of course they have discussed these topics extensively with many people; they do not exist inside a vacuum.

> You have an advantage to learn on others mistakes (e.g. made by those Java guys) and practice.

And the lesson learnt from studying other languages is "Don't add generics unless it's right for the language, even if that means choosing, on balance, to _NOT_ implement them at all".

Can you provide some examples of languages where people regret having implemented generics at all (as opposed to wishing they had been implemented in a different way)?

Java is the obvious example that springs to mind. Because of the requirement to be backwards compatible with Java 1.4, all the type information is erased during compilation. The call for reified types in Java has been heard for over a decade now.

C++ compile type templating is the cause of egregiously long compilation speeds. One of the original drivers for the creation of Go was the speed of C++ compilation.

I don't think you can separate a desire that generics was implemented a different way in these examples from the regret that their current implementation causes.

If you are willing to pay with execution speed, you can get fast compiles for generics. But C++ opted for fast execution speed and hence pay with long compile times.

I'd much rather have fast compilation and slower execution and some kind of generics, but the current situation is that people are insanely attached to their pride in fast program execution.

This is a common argument, but too much software is painfully slow to use. It becomes a user experience problem.

I thought the lesson was "adding generics after the point where you have to care about backwards compatibility is fraught with peril".

What is generics?

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