Type erasure  

Point

Type erasure is evil in java generics because types are reified in java. Reified types are an expectation of java programmers, and failing to re-ify generic types creates an un-natural limitation in the system as a whole.

In many other langauges, there is no expectation of reification and type erasure is a natural consequence of the compilation process.

A measure of reification is required to support runtime detection of bad down-casts. This is present in C#/Java in the form of InvalidCastException and in C++ is supported via dynamic_cast<>.

It seems tragic that supporting downcasts should limit the type system's design in such a pervasive manner--reification is quite expensive.

The questions:

  1. are downcasts really that important?
  2. are safe downcasts really that important?
  3. is knowing the type of an object at runtime really that important?

Some answers...

  • Haskell/ML say no to all.
  • Java says yes to all.
  • C++ says yes to (1) and possibly (1) and (2) depending on who you ask and how annoying they find rtti to be.
  • Scala has downcasting operators, but might not actually need them.
  • In C#, I very almost never downcast unless forced into it by a library (e.g. WeakReference). That said, I often need to jump through hoops to avoid it. Less pedantic developers seem to prefer downcasting to generics.

Counterpoint

Runtime type information is a commonly used escape hatch in JVM/CLR environments.

  • When type-level encodings get too gnarly, you can fall back on 'object'
  • You can fling objects through many layers of unsuspecting, non-generic code, and then go hunting for interfaces or base classes in a low level place
  • Checking things dynamically is often far easier than encoding the same things at the type level.
  • Dynamic systems are more honest and dramatically simpler to reason about because values do not change behavior based on static positioning.
Comments powered by Disqus