Friday, August 26, 2011

Scala: The Manifest

Scala, as Java, implements generics using type-erasure.
The JVM has no knowledge of the concept of "generic type", only the compiler does. As an example a List<Integer> will be compiled to non-generic List, and all type checks will be performed at compile-time.
At the contrary, C# uses reified type.

I do not want to discuss this subject here, but with reification a type-parameter is a class and you can use it as a class
class Cl1<T>{
    public void m(){
        return new T()
    }
}
whereas in Java (or Scala) you can't.
Obviously, there are pros and cons for each approach.
But is's definitely true that a C#-like behavior is often very welcome (in the factory method pattern, for example).
Working with Scala, you can take advantage of the implicit parameters and use the Manifest class.
class Cl1[T]{
  def m()(implicit mf: Manifest[T]) = {
    val cl = mf.erasure.asInstanceOf[Class[T]]
    cl.newInstance
  }
}
This is a little more verbose than C#, but satisfies the demand.
But there is one limitation: you can use this only on non-generic classes.
class Cl2[T] extends Cl1[T]{
  def m2 = m
}
Well, it could look correct but the compiler doesn't agree with you. That is because type T cannot be understood at compile-time (could be Int, String or whatever). You must specify the implicit parameter as long as you are working with generic types.
In fact if you write
class Cl2 extends Cl1[String]{
  def m2 = m
}
the compiler understands that the implicit parameter is Manifest[String] and doesn't need any other information.

No comments:

Post a Comment