Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin reified type parameter can't be used as type parameter in body of function

A reified type parameter in Kotlin prevents type parameter erasure and allows the type parameter to be known at run-time. This allows the following code to compile and run as expected:

inline fun <reified T> isA(value: Any) = value is T

However, when I try to use "T" as a type parameter instead of standalone I get a message that it is an erased type. This is demonstrated by the following code that is for illustrative purposes only:

inline fun <reified T> isListOfA(name: String): Boolean {
    val candidate = Class.forName(name)
    return candidate is List<T>
}

Is this due to a technical limitation? If so, what is that limitation?

like image 891
bartonstanley Avatar asked Jul 18 '17 17:07

bartonstanley


1 Answers

Evidently I did not formulate my question appropriately to get an answer of the form that I wanted. Most of the answers here are some variation of "because you can't do that in Java". Well, you cannot do x instanceof T in Java, either but you can do x is T in Kotlin. I am looking for the underlying practical roadblock not the Java rule. Rules are made to be broken, after all.

From my comment on the first answer here, the reformulated question is: if objectref is T can be made to work in Kotlin by some mechanism X why can't objectref is SomeClass<T> be made to work by that same mechanism?

tl;dr answer: Because there will be no Class object for SomeClass<T> at run-time.

Longer answer: First we must understand mechanism X, which is to generate an instanceof bytecode instruction for is T. This instruction takes objectref and the name N of some class C, where N is determined from context by the compiler. At runtime, the class C derived from N will be used to evaluate the objectref is T expression. In order for this evaluation to occur the class object for C must be instantiated. So to use this same mechanism for objectref is SomeClass<T> then N would be SomeClass<T>. Due to type erasure, there will not be a class object for SomeClass<T> so it is not possible to generate the needed instanceof instruction and thereby apply the same mechanism. In addition, the instanceof instruction cannot take a name of the form SomeClass<T>. Therefore, if objectref is SomeClass<T> is to work, some other mechanism Y must be found and implemented in Kotlin. Such a mechanism may or may not exist.

I know that some may say that this is the same thing as some of the other answers. However, for better or worse my learning style is to understand how things work down on the metal, and then synthesize this against the abstract model. In this case is the Java Generics notion of erasure is the abstract model (or part of it). Really, "erasure" feels squishy to me unless I understand at least one way that it is realized in a working implementation.

like image 179
bartonstanley Avatar answered Sep 23 '22 20:09

bartonstanley