In his talk Compilers are Databases, Martin Odersky presents an interesting variance corner case:
class Tree[-T] {
def tpe: T @uncheckedVariance
def withType(t: Type): Tree[Type]
}
T
is defined to be contravariant, because it is useful to think of a typed tree (Tree[Type]
) as a subtype of an untyped tree (Tree[Nothing]
), but not the other way around.
Normally, the Scala compiler would complain about T
appearing as the return type of the tpe
method. That's why Martin shuts up the compiler with an @uncheckedVariance
annotion.
Here is the example translated to Kotlin:
abstract class Tree<in T> {
abstract fun tpe(): T
abstract fun withType(t: Type): Tree<Type>
}
As expected, the Kotlin compiler complains about T
appearing in an 'out' position.
Does Kotlin have something similar to @uncheckedVariance
?
Or is there a better way to solve this particular problem?
Tree[Unit]
for untyped trees. It prevents more bugs (compile-time vs runtime error) and doesn't require you to work around the type checker (hey that's funny isn't it). Odersky was just Oderskying here. – Colman