<!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>