Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reified generics in Scala 2.10

The lack of reified generics in Scala is the thing that bugs me the most about the language, since simple things cannot be implemented without using complicated constructs.

Both Kotlin and Ceylon supports reified generics so its definitely possible to do so on top of the JVM. In the past it was said that Scala could not support them without a change in the JVM, but now Scala 2.10 is rumored to have limited support for reification. So my question is:

  • What can we expect for reification in Scala 2.10, will I for example be able to implement a generic trait multiple times ?. Just how limited is it ?
  • If Scala 2.10's reification turns out to be more limited than Kotlin and Ceylon. Why is that ?
like image 326
Lars Tackmann Avatar asked Dec 22 '11 14:12

Lars Tackmann


People also ask

Is reified generics and type erased generics are same?

The whole point is that reified generics have support in the compiler for preserving type information, whereas type erased generics don't. AFAIK, the whole point of having type erasure in the first place was to enable backwards compatibility (e.g. lower versioned JVMs could still understand generic classes).

What is a reified type?

In C#, reification is used to make parametric polymorphism implemented in the form of generics as a first-class feature of the language. In the Java programming language, there exist "reifiable types" that are "completely available at run time" (i.e. their information is not erased during compilation).

What is reified keyword?

"reified" is a special type of keyword that helps Kotlin developers to access the information related to a class at runtime. "reified" can only be used with inline functions. When "reified" keyword is used, the compiler copies the function's bytecode to every section of the code where the function has been called.

What is meant by reified generics in Java?

Reified Generics is a generics system that makes generics type information available at runtime. C# is one language that supports Reified Generics natively, as opposed to Java's Type-Erased Generics.


2 Answers

Your argument is flawed. Kotlin has not been released yet*, and Ceylon just had its first version released, and I'll quote one of the things it is missing from their announcement:

  • reified generics

So, excuse me, but what implementation proves it is possible? In fact, I haven't looked much at what Kotlin is promising, but what Ceylon is promising is just what manifests already provide, but in a transparent manner.

But let's consider the problem you described in your question:

trait Handles[E <: Event] {   def handle(event: E) } 

So, first of all, JVM doesn't provide any way of identifying type parameters in interfaces or classes, so E cannot be checked by JVM. You can, however, store information about what E stands for in each object that implements Handles, just like you could write this in Scala:

abstract class Handles[E <: Event : Manifest] {   def handle(event: E) } 

Next, let's see the method handle. Again, JVM provides no way of using type parameters in a method definition. The only way to implement that is to have handle accept Object as parameter: ie, type erasure.

And here's the deal: to make handle callable from Java, it must be type erased. And, if it is type erased, then it is subject to the limitation described in your question. The only way to get around that is to drop Java compatibility (which, by the way, is not available in Ceylon's first release either).

Yes, Scala will have reification (of some sort) on 2.10, according to Martin Odersky. But whatever it provides (and I'm betting on more transparent use of manifests to assert type equality), this particular limitation is intrinsic to JVM and cannot be overcome without dropping Java integration.

(*) Kotlin has a demo out now, and its reification -- so far -- is just a syntactic sugar for bundling manifests and instanceOf tests. It's still subject to all the same limitations Scala is.

like image 133
Daniel C. Sobral Avatar answered Sep 29 '22 15:09

Daniel C. Sobral


Kotlin has reified generics for inline function type parameters, as documented here: https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters. This has existed in Kotlin for some time now, they are used by many libraries already within the Kotlin ecosystem. Other answers here are out of date when referring to the Kotlin. Kotlin has been released as 1.0 since February, 2016.

Examples of reified generics in Kotlin, the famous TypeReference in Jackson, when used in the Jackson Kotlin module uses this code:

public inline fun <reified T: Any> ObjectMapper.readValue(jp: JsonParser): T       = readValue(jp, object: TypeReference<T>() {}) 

And the same thing from the Kotlin based Injekt library:

public inline fun <reified T: Any> fullType(): FullTypeReference<T>      = object:FullTypeReference<T>(){}  public inline fun <reified T : Any> injectLazy(): Lazy<T> {     return lazy { Injekt.get(fullType<T>()) } } 
like image 23
Jayson Minard Avatar answered Sep 29 '22 14:09

Jayson Minard