Brian Goetz considers unified typesystem on JVM harmful


#1

There is an interesting discussion about the plans to support primitive types with generics in Java. Particular interesting is the answer from Brian Goetz. He considers it a bad idea to try to "simulate" a unified type system on the JVM, which doesn't support this concept itself.

Kotlin tries to unify the type system on the JVM. Do you think the critism from Brian Goetz are valid for Kotlin?


#2

He considers it a bad idea to try to "simulate" a unified type system on the JVM, which doesn't support this concept itself.

Well, first of all, Brian's point is a little different from ours: he is talking about introducing a common supertype "Any" of both java.lang.Object and all the primitives. This is not what we are doing: we have "Any" being exactly "java.lang.Object" (and primitives assigned to Any are auto-boxed), which Java can not afford, for one thing, due to compatibility issues. This is a minor difference, but nevertheless.

Then, Brian rightfully refers to Scala’s bad experience with unifying the type-system. I think that it’s largely a question of how much you’d like to unify the type system. Scala’s ambition was, among other things, to

  • have implicit conversions working for primitives
  • unify arrays with collections
  • make Nothing an equally well’behaved citizen as others


Kotlin prohibits any kind of implicit conversions (exactly because of the primitives), and it seems to woks well enough (some surface-level smoothing for rough edges pending). Kotlin does not attempt to unify arrays with collections (indeed, we even have IntArray and such), Kotlin discriminates against fictitious types, like Nothing (e.g. you can’t create an instance of Array<Nothing>). Likewise, our design (I believe) eliminates other pitfalls possible thereof.

I would like to emphasize that Brian’s point is still valid for Java. Because you can’t throw things out of a language already in use. For example, Java can’t get rid of its semantics of comparison for primitives, which heavily involves implicit conversions, and will break if wrappers and true primitive values are intermixed.

Bottom line: any abstraction leaks. Nevertheless, some abstractions work well enough (see inner classes or ++ operator in Java, or, arguably, even erasure for generics). We believe that our approach to unification of the type system works well enough. Which, again, does not render Brian’s argument invalid, for his context is different.


#3

we have "Any" being exactly "java.lang.Object" (and primitives assigned to Any are auto-boxed), which Java can not afford, for one thing, due to compatibility issues.

Is this approach compatible with Oracle's plans to support generic types over primitive types without boxing? How will Kotlin support generics with primitives types?


#4

This approach aligns one-to-one with the current Java's approach (the difference being purely syntactic), so we will be able to at least do the same as Java ends up doing.

I would like to point out that nobody knows for sure which way Java will go with specialization of generic classes, and the design presented recently is an early
experimenting draft, not a JSR (here’s the JEP, its status is “Candidate”).