<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4" face="monospace">Received on valhalla-spec-comments.<br>
<br>
Notes from the legislative analyst:<br>
<br>
The author observes that nullability by default is a bad default,
and that we should retroactively reinterpret unadorned type names
as if they were null-restricted. </font><font size="4" face="monospace">The author also suggests changing some
long-standing policies, such as allowing the `--target` version to
be less than the `--source` version. </font><br>
<font size="4" face="monospace"><br>
While the author purports this to be a mere "better syntax", this
is actually an incompatible, retroactive semantic change. <br>
<br>
The author is compelled by the notion that "non-nullable would
have been a better default", which is unquestionably true (and
borne out by empirical efforts of annotating existing libraries.)
However, retroactively changing what "String" means would, quite
literally, be the biggest incompatible change in Java's history.
<br>
<br>
The issue that nullability by default was a bad choice, and the
desire to find an acceptable way to migrate away from this choice,
is fully understood. But we will not be discussing it for the
time being, because we simply have way too much work that isn't
literally "the biggest incompatible change every suggested for
Java" to add this to our plate at this time. <br>
<br>
<br>
</font>
<div class="moz-forward-container"><br>
<br>
-------- Forwarded Message --------
<table cellpadding="0" cellspacing="0" border="0" class="moz-email-headers-table">
<tbody>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">Subject:
</th>
<td>Null-Restricted and Nullable Types</td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">Date: </th>
<td>Sat, 23 Nov 2024 21:03:32 +0100</td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">From: </th>
<td>Enno Thieleke <a class="moz-txt-link-rfc2396E" href="mailto:enno.thieleke@gmail.com"><enno.thieleke@gmail.com></a></td>
</tr>
<tr>
<th valign="BASELINE" align="RIGHT" nowrap="nowrap">To: </th>
<td><a class="moz-txt-link-abbreviated" href="mailto:valhalla-spec-comments@openjdk.org">valhalla-spec-comments@openjdk.org</a></td>
</tr>
</tbody>
</table>
<br>
<br>
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div>Hello,</div>
<div><br>
</div>
<div>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 <i>slightly</i>
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.</div>
<div><br>
</div>
<div>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 <i>meant to be</i>
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.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>Let's take a look at how the flags would affect
what:<br>
</div>
<div>
<ul>
<li>`-source 30 -target 30`<br>
`String` becomes null-restricted, `String?`
becomes its nullable pendant, bytecode would
be generated with null checks and further
information on nullable where required.</li>
<li>`-source 30 -target 29`<br>
`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 <i>could</i> be generated with
backward compatible null checks, but no
information on nullable.</li>
<li>`-source 29 -target 29` is as if Java 29 is
used.</li>
<li>`-source 29 -target 30`<br>
`String` remains nullable (just like above)
and bytecode would be generated with
information on nullable pretty much
everywhere, because nothing can be
null-restricted.<br>
</li>
</ul>
<div>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.<br>
</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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".</div>
<div><br>
</div>
<div>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.<br>
</div>
<div><br>
</div>
<div><span>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.</span></div>
<div><br>
</div>
<div>Thank you very much and regards</div>
<div>Enno<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>