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.