Cedric recently brought up the topic of type erasure, concluding:

All in all, I am pretty happy with erasure and I’m hoping that the future versions of Java will choose to prioritize different features that are more urgently needed

Well, I suppose erasure isn't the thing I hate most about Java, but it's certainly up there. Java's system of partially reified types actually adds a surprising amount of complexity and unintuitive behavior to the type system.

From a pure language-design point of view, I think a partially reified type system is one of the worst decisions you could possibly make. Either reify all types, like C#, or reify none of them, like ML. And look, there's certain language features that simply don't play nicely with type erasure. A case in point: overloading. You can have type erasure, or you can have overloading (or, like Ceylon, you can have neither). You can't have both type erasure and overloading. No, Java is not a counter-example to this! In terms of language design, Java's approach to reification is almost impossible to justify except as a totally half-baked and misconceived workaround for simply not having time to Do It Right.

But Cedric's coming from a purely practical point of view, saying the problems don't actually bite him much when he's doing real work. Well, OK, I can see that. So here's the practical reasons why I think reified generics are needed, and why they should be added to Java if that could be done without messing up Java's type system even further.

Frameworks

Many frameworks depend upon having reified types. Type argument erasure cripples frameworks that work with generic types, and results in horrid workarounds like this one in CDI.

Typesafe narrowing

Instead of a Java-style instanceof operator, and C-style typecasts, Ceylon provides a construct for narrowing the type of a reference in a totally statically typesafe way. You just can't get ClassCastExceptions in Ceylon.

But this functionality depends upon having reified generics. Until we implement reified type arguments, we can't provide any mechanism to narrow to a parameterized type. Right now, you simply can't narrow an Object to a List<String>.

You might think that this is a problem with Ceylon, but really, the situation isn't much better in Java. The instanceof operator doesn't support types with type arguments, and casting to a type with type arguments is a totally unsafe operation! I just don't think that's acceptable behavior in a language with static typing.

Inter-language interoperability

Interoperability between statically-typed JVM languages is going to get really messy when some of the languages support reified generics and some don't. Especially since it's easy to imagine that those languages which do support reified generics won't support them in an interoperable way. This could turn out to be a real problem for the vision of a multi-language JVM.


Back to top