Null-Restricted and Nullable Types

Enno Thieleke enno.thieleke at gmail.com
Sat Nov 23 20:03:32 UTC 2024


Hello,

after seeing Brian's very good talk about project Valhalla he held at the
JVM Language Summit two months ago, I'd like to suggest a *slightly*
different syntax for null-restricted types. The motivation for it is
simple: We'll be using that syntax for 20+ years, so it should be "nice".
While this is a highly subjective thing, I think we can agree that having
to write (and read) less is preferable to more - even when it comes to
single characters.

I think the "bang" for null-restricted types is not necessary. While I
can't provide any numbers, I'm making the (bold) claim that the majority of
variable declarations across all Java source code on the planet is in
fact *meant
to be* null-restricted. So instead of writing `String!` for "this mustn't
be null" we should really be writing `String`. And when it comes to
nullables, we should be writing `String?` as suggested in Brian's talk and
just like in other languages.

The obvious question is: How can we make existing Java code compatible when
the same code suddenly changes semantically if we update to a new Java
version? I think this is where the `-source` and `-target` flags of the
compiler come into play. Let's assume Java 30 considers `String` to be
null-restricted and Java 29 doesn't.

Let's take a look at how the flags would affect what:

   - `-source 30 -target 30`
   `String` becomes null-restricted, `String?` becomes its nullable
   pendant, bytecode would be generated with null checks and further
   information on nullable where required.
   - `-source 30 -target 29`
   `String` becomes at least syntactically null-restricted (compile time
   errors would occur within the same compiler run if used with `null` or a
   nullable pendant), `String?` becomes its nullable pendant, and bytecode
   *could* be generated with backward compatible null checks, but no
   information on nullable.
   - `-source 29 -target 29` is as if Java 29 is used.
   - `-source 29 -target 30`
   `String` remains nullable (just like above) and bytecode would be
   generated with information on nullable pretty much everywhere, because
   nothing can be null-restricted.

But what if we compile against a library? The compiler can figure out, by
using the class file version, if parameter, return and field types are
null-restricted or not. If the class file version is for Java 29, all types
are effectively nullable. If the class file version is for Java 30,
null-restrictedness is implied (no information needs to be present, in fact
it needn't exist at all) and nullable types are specifically marked as part
of the compilation process of a class file.

This way it would be possible to use the new null-restricted types by
default, but developers can opt-out, which would make sense for a lot of
Java codebases out there in the beginning.

However, it might also be a good idea to have a special opt-in (or out)
compiler flag, instead of the `-source` flag, for making null-restricted
types the default or not, in which case the class file version can't be
used to determine null-restrictedness and I couldn't come up with a
different solution than introducing a flag in the byte code. With a special
compiler flag it would be possible to use new Java 31 and 32, etc.
`-source` levels, without ever activating the null-restricted types by
default, which would make the transition to null-restricted types easier,
because it wouldn't be "enforced".

In essence Java would give developers a choice: Stick to "legacy" nullable
types or enable null-restricted types for the entire code of a compile
process at once.

This may or may not be a naive approach to dealing with the situation, I'm
not sure, but I'd like to emphasize that your decision will set the new
syntax in stone for the foreseeable future and should therefore prioritize
good code readability, as it is crucial and in my opinion one of the key
features of the Java programming language and I hope that it still will be
in the years to come.

Thank you very much and regards
Enno
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-comments/attachments/20241123/e02161aa/attachment.htm>


More information about the valhalla-spec-comments mailing list