Reified Type Parameters

“Reify” is a word in English, meaning:

to consider or represent something abstract as a material or concrete thing; to give definite content and form to a concept or idea

(from the Merriam-Webster dictionary)

From a programming standpoint, the early January 2021 edition of Wikipedia has:

By means of reification, something that was previously implicit, unexpressed, and possibly inexpressible is explicitly formulated and made available to conceptual (logical or computational) manipulation. Informally, reification is often referred to as “making something a first-class citizen” within the scope of a particular system.

Despite the flowery descriptions, the refied keyword in Kotlin has a very specific meaning: keep a generic type around for use at runtime.

Type Erasure (Other Than Via the Backspace Key)

We saw the use of generic types earlier in the book. One key aspect of generic types is that they are purely something used at compile time. The Kotlin compiler uses generic types to help ensure the validity of our code, yelling at us if we violate some contract. However, the compiled code has no knowledge of those generic types.

For example, collections like List have a filterIsInstance() operator. This returns another collection whose types match a particular type. We could try to define our own similar function, filterByType():

fun <T> List<*>.filterByType() = this.filter { it is T }

fun main() {
  println(listOf(1, "this", 3, "is", "a", 1337, "mess").filterByType<String>())
}

Here, filterByType() is declared as an extension function of List<*>, where the wildcard means “we are not concerned about the type of objects in this List”. The function declares a generic type T, and the implementation of the function uses the regular filter() operator with a lambda that returns true only for those objects that are of type T.

In theory, this should work.

In practice — such as if you try this in the Klassbook scratch pad — it fails with a compile error:

Cannot check for instance of erased type: T

The is check is a runtime check — we do not know at compile time what is in the List courtesy of the wildcard. But that implies that at runtime we know what type T is, and by default, we do not, because types get “erased” by the compilation process. Usually, our attempts to use a generic type at runtime get detected by the compiler, and we get an error message like the one shown above.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.