How will Kotlin handle Valhalla?

A future version of Java, maybe Java 10, will let you write HashMap<int> and have a type-specialised version of HashMap be produced at runtime. Ditto for other generic types.

The Kotlin type system does not distinguish between primitives or boxes. You can only write HashMap<Int>. That seems like a problem without a good solution.

  1. Kotlin could always translate Map<Int> to pre-Valhalla boxes and maintain binary compatibility with previous Kotlin and Java code, at a cost of efficiency.
  2. Kotlin could always translate Map<Int> to Map<int> at the bytecode level when Java 10 is being targeted, but this would break the ABI of previously compiled modules.
  3. Kotlin could try and surface the difference at the language level via annotations or new modifers, but that would lose the simplicity benefits that came from unifying these concepts.

Alternatively, Kotlin could steal the notion of a targetSDK from Android. Thus behaviour would be to ignore post-Valhalla generics when compiling code by default, but if a file/class/function was annotated with @TargetSDK(10) then the code would be compiled in the most efficient way possible, using specialised generics for value types. Thus developers would have to opt in to the ABI breakage. The notion of a “target SDK” would also allow various other issues to be resolved.

What do you think, JetBrains?

3 Likes

Kotlin could always translate Map to Map at the bytecode level when Java 10 is being targeted, but this would break the ABI of previously compiled modules.

Not necessarily: if we provide a way to define a boxed version, i.e. through something like HashMap<Int.Boxed>, the old modules can still work, and the new ones can interact with them when needed.

And we are definitely going to support different target platforms (this is not only about SDK, but the VM too). Whether this should surface in the code in terms of annotations that change how things are compiled, I can’t say, but the idea looks dangerous.

1 Like