7 ms·
Generics were added so late because they had to figure out how to do it properly, correctly, on the first time.
by akerro 7y ago
Generics were added so late because they had to figure out how to do it properly, correctly, on the first time.
- thechao 7y agoGenerics in Java are giant hack from the early 2000’s to maintain backwards compatibility with 1990’s-vintage JVMs. C#’s generics we’re done right.
- eropple 7y agoI'm of two minds of that, these days. I came from C# so of course reified generics were of course better, of course--but these days I would rather have them in Java more and in C# less. I often find myself wanting to write the moral equivalent of `IFoo<?>` in C# and end up having to have two separate interfaces, etc. just to have a way to handle a list of a thing that I end up working on in an abstract manner. (Though I'd caveat that that is more of a gamedev-related concern than in Java/Kotlin, which I write for work.) I do appreciate, though, that when Microsoft decided to do generics for C#, they did so decisively. These days, when C# gets a new feature, it seems like it's the complete opposite of decisively delivered.
- jimmaswell 7y agoYou mean like this, right? class A {}; class A<T> : A {}; I don't mind that. It can even be an aid to organization - all the generic stuff goes in the generic class, all the stuff that doesn't rely on that can go in the base class. But it would be nice to use something like <?>. Too bad generics don't inherit implicit casts, like A<int> to A<object>.
- eropple 7y agoI do mean that, and I do mind it a lot when I'm so used to just being able to erase the generic. There are performance implications to type erasure, to be sure, but when our computers are mostly all future machines from beyond the moon, I'm more interested in minimizing the impedance between my brain and a solved problem.
- jimmaswell 7y agoThis is the only non-bad consequence of type erasure I'm aware of. On the other hand, a lot of code I've written in C# would be impossible or severely hacky without type retention, like "new T()", "T is Thing", finding all classes that are derived from T, etc.
- eropple 7y agoTBH, I'm just as happy passing a factory method in for that sort of thing. Because it allows you to do both and pick the one that makes the most sense for you in a given situation.
- RHSeeger 7y agoAnd they failed. They did the best they could, but the fact that they were added onto the language later (plus the desire for backwards compatibility) means there are lots of gaps and warts in what they wound up implementing.
- bunderbunder 7y agoAnd the hacks to work around them started rolling in quite quickly. For example: http://gafter.blogspot.com/2006/12/super-type-tokens.html http://gafter.blogspot.com/2006/12/super-type-tokens.html At its root, the real problem here isn't "reification good" vs "reification bad", per se. Haskell has an excellent implementation of generics, and erases types far more aggressively than Java does. C# also has a very good implementation of generics, this time based on reification. The problem is more that Java's particular mix of design decisions resulted in a language that operates at cross purposes with itself. Once upon a time, back in the beginning, Java was a reflective language. Being reflective requires type information to be available at run time, though. When Java decided to use type erasure in its implementation of generics, they created a really bad set of interactions: They kneecapped reflection, so now you can no longer call Java truly reflective; it's only partially reflective. You can no longer effectively and accurately reflect on what have come to be some of the most-used classes in the language. And, at the same time, they forever sealed a rather important corner of the type hierarchy off from generics. They also delayed a bunch of type checking until run time - after types have been erased - so that certain things can just never be made to cleanly type check. Meaning you also can't say Java is any more than partially generic.
- mcguire 7y agoIIRC, the choice was between Java 5's version of erasure or drastically modifying the JVM, with the likely result that the new Java would be incompatible with the old Java. (Like C# has done.) This was considered unacceptable at the time. (Unlike C#.)
- james-mcelwain 7y agoErasure is important in allowing interop from other JVM languages. Reified generics would be nice from the perspective of just writing Java, but the interop story on the JVM is one of its best selling points.