"MINUS_NULL" and the future of explicit nulls

Ah, this is not the message I intended to convey. Of course Java interop is important. What I find not-obviously-very-important is to faithfully represent a bound of java.lang.Object MINUS_NULL in the Scala type system.

It’s worth remembering that java.lang.Object itself is already not faithfully represented. We cannot know whether it’s supposed to mean AnyRef or Any, so we represent it as this weird ambivalent <FromJavaObject> that tries to accommodate both use cases.

This is the only reason we have this discussion/issue. If java.lang.Object unambiguously meant AnyRef, then under explict-nulls, the translation of Object UNION_NULL would be AnyRef | Null and that of Object MINUS_NULL would be AnyRef. Done, easy.

That is what happens for every other class type: String UNION_NULL becomes String | Null while String MINUS_NULL becomes String.

Because we try to accommodate jl.Object being interpreted as Any, it becomes less clear what to do with MINUS_NULL. And this is why I think a <FromJavaObjectNonNull> is perhaps the way to go.


This will independently be fixed by Proposal: Fixing null.methodOfAny() under explicit-nulls

In this direction, we have no problem. If from Scala we know something is an AnyRef, we can tell Java it’s an Object MINUS_NULL. And if it’s an AnyRef | Null, or an Any, we can tell Java it’s an Object UNION_NULL.

The issue exposed in this thread is only about interpreting Java into Scala. Not to communicate from Scala to Java.

Using a different number of type arguments is a non-starter. The mismatch between the Java API (and its documentation) and Scala’s interpretation and usage would be devastating.

This is precisely what <FromJavaObject> achieves today: it both under- and over-corrects Object as AnyRef or Any depending on usage.