Hacker News new | ask | show | jobs
by Daishiman 4131 days ago
This answer is slightly infuriating:

> Q: Lack of generic collection classes like in Java’s Guava library?A: For 90% of cases, slices and maps do what you need. For the other 10%, you might consider whether your package should own the logic of those special containers, instead of using an external package.

I read this as:

"We're not willing to put in the hard work on thinking of a decent generics implementation, despite decades of working solutions with a myriad of choices in tradeoffs, so you'll have to do the hard work of integrating a dozen different collections libraries and who knows how many different, after-the-fact, mediocre strategies to the generics issue, each slighly off, all of them conceptually incomplete somehow, and with the slight bugs that come from not having a well-trodden path for an essential component of most programming languages."

2 comments

I am not a member of the Go team, just a contributor. I represent only my own opinions, please don't put words into my mouth.
This is my own personal opinion on core dev's position and no one else's, but to me generics and dependency management have always been the pink elephant in the room.

I can wait for features; I'm patient. But the downright refusal of Go's core team to even begin to address this issue is not just a technical problem, but a communications one. This is clearly big for a lot of people, and I have yet to see any serious responses aside from either "you domain model's wrong if you need generics" or "deal with it".

In contrast (just picking this language for its community outreach, not because of any perceived technical competition), Rust's core devs have been forthcoming about practically every objection they've gotten. Their answers are clear, detailed, not demeaning, and constructive. When they don't know, they're honest about it, and when answers are hard, they take the time to explain. But I have never heard of anyone being belittled for not understanding lifetimes or the borrow checker.

Yet it seems that somehow if I have a bone to pick with Go not being able to dispatch functions by argument or arity, or with how its simplicity ends up with codebases a lot of people would consider much more verbose than necessary, it's just that I don't "get it". The problem isn't even in the accusation; I just don't even receive examples or reasonable explanations, something I'm used to in related language discussions.

I was willing to give the language a pass on these things when it was just getting started and a lot of the classical, early product criticisms were abound. But it's gotten tiring; the number of unanswered questions is remarkable by now.

If you haven't found any "serious response", maybe it's because you haven't searched enough.

Here is a "clear, detailed, not demeaning, and constructive" answer of Ian Lance Taylor that addresses your concerns:

https://groups.google.com/d/msg/golang-nuts/smT_0BhHfBs/MWwG...

I would guess his answer will not suit you, but you can hardly argue the Go team ignores the issue or refuses to talk about it.

Several members of the Go team have put a lot of time into studying and prototyping various implementations of generics.

If you look through the mailing list archives you will find many emails from Ian Lance Taylor on the topic.

I'll be completely honest: it's one of the most BS reasons I've ever read in a technical discussion.

How can we talk about high performance when:

* The current "generics" mechanism (interface et al) does runtime introspection, which is just about as slow and unwieldy as it gets * There is no option for pervasive, truly high-performance data structures since everything is a map (which comes with its own type parametrization as an exception to everything else), and if you don't like the hashing algorithm, tough luck. * You have a garbage collector running in the background, which is barely tunable compared to the options other runtimes have

Talking about performance when it's convenient as an argument against generics but disregarding the other holes in the language is not reasonable, because I would say that the choice of implementation for native maps is probably far more important for high performance. Yet here we are, no one complaining.

So we can really discard the performance argument, thus there is now an ample, valid set of choices for generic programming, several of which don't go against the goals of fast compilation.

Speaking of fast compilation; pretty much everything is going to be faster than C++ templates, since the entire compilation chain in C++ is slow.

It would be unreasonable to have designed a generics implementation into Go 1 that did not cover the builtin polymorphic map, slice, and append. A simple set of orthogonal features is an important principle in Go.

For these, performance is most certainly critical.

He is not putting words in your mouth, he's stating his own interpretation.

No sane person would read "I read this as" and assume that this is in fact exactly what the speaker said, nor should any speaker assume "I read this as" is meant as a defamation or misquote.

In addition, you being a contributor not a core team member does not change what you said in the least. A language's design, even if it seems like there's a tight core, is ultimately decided in part by all contributors and the community around it as well.

The use of the opening phrase "We're not willing ... " implies that the OP interpreted my statements as a policy of the wider Go team.

I have no knowledge of any such policy and represent only myself on stage. You can think what you like about my statements, just don't generalise them to anyone else.

But isn't that effectively what the core team did indeed say? They just dismissed everyone's implementations of generics as having a downside, couldn't come up with anything better, then just left it at that. (Edit: This is just my knowledge from a while ago. There's some mailing list thread where every existing way to do generics is dismissed for one reason or another, and well, Go still doesn't have that one feature.)

Also, "Sans runtime"? When did that happen? Last I heard, Go had a fairly substantial runtime to it, making it unsuitable for many places, and not trivially possible to just link right into any old program. And without a runtime, it'd be hard to have a GC, eh?

I think you meant "Statically linked", and nothing at all about runtimes. Rather large difference. FWIW, you can statically link many things, including C#. Which is how C# is deployed e.g. in bestselling iOS apps (and running on iOS has gotta be far from being "tied to the hip" of Windows).

(As a comparison, Rust is actually what is generally meant by "sans runtime", as in you can just call right into a Rust function without setting up anything else (just don't like, call panic or something).)

> despite decades of working solutions

Which "working" solutions? Has anyone solved creating a type system that offers OO/inheritance, generics, mutability and isn't mind-bogglingly complex?

What is your definition for a "working" solution? I don't think any of the current languages we have fit this description, since all of them are capable of producing type errors that are way too complex to comprehend.

> with a myriad of choices in tradeoffs

Yeah, but how do you decide on which tradeoff to settle for? And why is the tradeoff to not engage in this mess not a just as valid one?

> so you'll have to do the hard work of integrating a dozen different collections libraries and who knows how many different, after-the-fact, mediocre strategies to the generics issue, each slighly off, all of them conceptually incomplete somehow

You're missing the point. Solving the generics issue for a specialized case, even if just on a library-level, is much easier and has much less impact on applications than solving the general case and forcing that solution onto every bit of code in that language.

I don't think the author is advocating using a general purpose 3rd-party library for containers, but rather writing your own special-purpose ones for the few cases where the on-board tools aren't enough.

> with the slight bugs that come from not having a well-trodden path

Localized bugs are easier to solve than the type errors common to that "well-trodden path" you talk about, which may span an entire application.

..not that there is any consesus on what exactly that "well-trodden path" is, since as you mentioned there's a myriad of tradeoffs.

> Which "working" solutions? Has anyone solved creating a type system that offers OO/inheritance, generics, mutability and isn't mind-bogglingly complex?

Pretty sure OCaml would match your definition of "not mind-bogglingly complex" as well as "type system that offers OO/inheritance, generics, mutability".

What would you want OO for? First-class functions + HM + typeclasses work fine.
Unification is not a substitute for semi unification.