I tried Scala a few years ago. There are several good ideas in it, but I found the language to be a bit too complicated to master. But I recently stubbled upon a paper on Scala generics that might change my mind about using Scala.
Scala Generics used to work in a similar way as Java Generics: via type erasure. One main reason is compatibility with Java, another is that C++ like templates make the code base blow up. Scala Generics offered some additional behavior (the variance/covariance notion). C++ templates, however, have some very interesting aspects: one is that everything is done at compile time, the other is performance. If the generics are involved in any kind of computation intensive task, all the Java type conversion will create a significant overhead.
Now Scala has @specialized (since Scala 2.8). Annotating a generic type with @specialized will generate code. One has the choice to accept the performance penalty or to get all the performance but accept the code blow up. I think this is very useful.
If you read the paper you will see that the performance implications of this are not always small.
UPDATE: I thank the readers for pointing that this work only with primitive types to avoid autoboxing. It is still valuable but less than I first thought.
But this is only code generation for the "primitive" types: int, long, double etc...
ReplyDeleteFor overcoming erasure look at Manifest.
Maybe you should mention for what types that works.
ReplyDeleteI think you've misunderstood what @specialized does. It's not to get around type erasure, it's to optimize collections (for example) for primitive types. Like template specialization in c++.
ReplyDelete"If the generics are involved in any kind of computation intensive task, all the Java type conversion will create a significant overhead."
ReplyDeleteThis holds for primitive types only, AFAIK. When you store objects in a List for example, there is no type conversion going on, in this case the type parameters are processed only at compile time.
If you store primitive values, the overhead comes from the (auto)boxing of primitive types to objects, not from genericity.
Sorry about my above comment, I was wrong. "List<String> l; String s = l.get(0);" will also use a "checkcast" instruction.
ReplyDelete