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

Java`s generics have had issues due to use site variance, plus the language isn't expressive enough, leading its users into a corner where they start wishing for reified generics (although arguably it's a case of missing the forest from the trees).

But even so, even with all the shortcomings, once Java 5 was released people migrated to usage of generics, even if generics in Java are totally optional by design.

My guess to why that happens is that the extra type safety and expressivity is definitely worth it in a language and without generics that type system ends up staying in your way. I personally can tolerate many things, but not a language without generics.

You might as well use a dynamic language. Not Python of course, but something like Erlang would definitely fit the bill for Google's notion of "systems programming".

The Go designers are right to not want to introduce generics though, because if you don't plan for generics from the get go, you inevitably end up with a broken implementation due to backwards compatibility concerns, just like Java before it.

But just like Java before it, Go will have half-assed generics. It's inevitable.

Personally I'm sad because Google had an opportunity to introduce a better language, given their marketing muscle. New mainstream languages are in fact a rare event. They had an opportunity here to really improve the status quo. And we got Go, yay!

After some initial enthusiasm due to its gentle learning curve (actually, the Golang learning curve is nearly non-existent for an experienced programmer), I got sick of Go programming pretty quickly. Writing anything non-trivial will have you fighting against the limitations of the language (e.g., lack of generics which is particularly aggravating when trying to write a library).

I've mostly moved on to Clojure for programming backend services. I still use Go for the occasional small utility program due to its speed and ease of deployment, though.

I've programmed scores of libraries in Go and found it pleasant, in fact it's more pleasant writing a library in Go than in any other language I've used.

I've never once even considered the fact that I might need generics because I've never run into an unsolvable problem or an extremely inelegant engineering solution. I see a lot of people claiming that the lack of generics is a big problem but no one is actually showing a concrete case where generics are necessary.

C doesn't have generics but we never have this discussion when we talk about C.

If you have a []T and you want to apply a function to make it into []K, you need to explicitly make a loop in every case. You might not think that's that bad, but note that T and K could also be interfaces such that T is a superset of K. In that case Go, T can be used as K but []T cannot be used as []K (meaning you have to do an explicit loop for something that should be an implicit type conversion).

That is a trivial example where generics help. And yes, the endless boxing and runtime type assertion does make your code slower eventually (see the comment from the libcuckoo authors).

This is one of the reasons why the container and sort stdlb libraries are such a joke. They're not generic so they have to special case every different type. With generics, the entire sort package would just be a function that takes []Ordinal and sorts it. Container would similarly only require one implementation of each data structure (because they would be generic).

I find it hard to believe that you've programmed "scores of Go" and you've never hit any of these issues. I also have programmed plenty of Go, and these problems are just frustrating.

Been using it for years now in a setting with lots of data and never had any problems.

If that's true then you might not benefit from generics directly. But you will benefit from having an ecosystem of libraries that take advantage of generics. And even if you don't use other people's libraries, not everyone in the world happens to be as lucky as you and they do need generics to make their lives easier.

But again, I still severely doubt you've never run into a problem with Go's lack of generics. I ran into it after about 3 months of working with Go. Maybe you didn't find the work-arounds problematic, but that doesn't mean that the original limitation (no generics) doesn't cause problems. You just choose to accept the work-arounds as the "right way" of doing things.

If you haven't already, I would recommend looking at Rust or another modern language that has generics to see what sort of benefits you can get out of it that you can't directly get with Go. Personally the fact that if T implements an interface I won't let you use []T as []I is pretty silly IMO. Rust lets you do that with the From trait, and you can even do it even more generically with the From trait using a generic T.

> C doesn't have generics but we never have this discussion when we talk about C.

Sure it does, a light weight version was introduced in C11.


Besides, C gets an excuse because the language was designed before generics were even invented, and with pre-processor macros is it possible to implement a poor man's generic system.

Maybe you don't, but I often have a very similar discussion in C code reviews: The unfortunately ubiquitous use of void pointers.

Similar background here, but I found Go refreshingly liberating because everything in the language makes sense and there isn't a lot of magic going on. I might write a bit more code but its crystal clear how it works and more importantly I can come back in 6 months and grok the code. In face, this is the first language i've used in 25 years of coding where I can read anyones code and grok it. go fmt might be the best part of go.

The point of Go 2.0, IIUC, is that it throws away backwards-compatibility guarantees, so if they want to do something in Go 2.0 that breaks correct go1 code to support generics, that's on the table. So backwards-compatibility nastiness is not guaranteed.

Not quite. The article mentions that Go 1 code needs to be able to coexist with Go 2 in the same codebase.

So, at runtime, Go 1 code needs to be able to work with Go 2 types. That will impose some restrictions, I imagine.

>The article mentions that Go 1 code needs to be able to coexist with Go 2 in the same codebase.

Interesting. Are there any other languages where that is allowed? I'm assuming that by "codebase" you mean all the code that gets compiled into one program or library (for compiled languages), or is part of one program or library (for interpreted languages). And I don't mean the case where only a common subset of Lang X v1 features and Lang X v2 features are used in the same codebase (because in that case, there is no issue). That latter case is possible, for example, in Python, and probably some many languages too. In fact by the definition of the case, it should be possible in all languages.

I would just read the article. Basically, the restriction they want to impose is to make sure that you can import v2 code into a v1 codebase and vice-versa with a v2 compiler. So that means any syntax breakage would need to be versioned or otherwise inferred, I guess.

>>>>The article mentions that Go 1 code needs to be able to coexist with Go 2 in the same codebase.<<<<

>>Interesting. Are there any other languages where that is allowed?<<

C / C++

Perl 5/6

The various language feature pragmas in Haskell.

Interesting, didn't know this about C/C++, though I may have guessed it about Perl.

> I'm assuming that by "codebase" you mean all the code that gets compiled into one program or library


> Are there any other languages where that is allowed?

One would be Racket, a Lisp which allows you to pick a syntax flavour using the #lang directive: https://docs.racket-lang.org/guide/Module_Syntax.html#%28par...

My guess as to why people in Java use generics so much and switched to them so quickly is the squiggly yellow lines in their IDEs. A lot of Java code is easier to read/write with explicit and implicit casting and no use of generics. And the type erasure makes for sometimes unintuitive behavior at runtime. Being familiar with Java, I appreciate Go's skepticism toward generics because maybe just maybe they'll figure out a way to add them after the fact in an elegant way.

> Java`s generics have had issues due to use site variance

Use site variance can be really powerful when you're dealing with invariant data structures like Lists. You can then treat them like covariant or contravariant depending on a particular method call at hand.

Registration is open for Startup School 2019. Classes start July 22nd.

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