<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">From the -comments list.  <br>
        <br>
        My comments: this posting feels mostly like a solution without
        stating what problem it is trying to solve, so its pretty hard
        to comment on.  But ...<br>
        <br>
        <blockquote type="cite">
          <div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">Would it be
                possible to decomplect nullability from a variable's
                encoding-mode (reference or inline)?</font></span></div>
        </blockquote>
      </font></font><font size="4"><font face="monospace"><br>
        Not in reality.  A null is fundamentally a *reference* (or the
        absence of a reference.)  In theory, we could construct the
        union type int|Null, but this type doesn't have a practical
        representation in memory, and drags in all sorts of mismatches
        because union types would then flow throughout the system.  So
        the only practical way to represent "int or null" is "reference
        to int."  Which is to say, Integer (minus identity.)  <br>
        <br>
        <blockquote type="cite">
          <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">If this is
                possible, maybe Valhalla's Java could have a user-model
                like this:<br>
              </font></span></div>
        </blockquote>
        <br>
        You should probably start with what problem you are trying to
        solve.  <br>
        <br>
        <br>
        <br>
      </font></font>
    <div class="moz-forward-container"><br>
      <br>
      -------- Forwarded Message --------
      <table class="moz-email-headers-table" cellspacing="0" cellpadding="0" border="0">
        <tbody>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">Subject:
            </th>
            <td>nullable-inlined-values on the heap</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">Date: </th>
            <td>Thu, 30 Jun 2022 23:02:17 +0100</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">From: </th>
            <td>João Mendonça <a class="moz-txt-link-rfc2396E" href="mailto:jf.mend@gmail.com"><jf.mend@gmail.com></a></td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">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 style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">Hello,</font></span></div>
        <div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">Would it be
              possible to decomplect nullability from a variable's
              encoding-mode (reference or inline)?<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">I have been
              looking at the C# spec on "nullable-value-types" and I
              wonder if the Java runtime could do something similar
              under the hood to allow nullable-inlined-values, even on
              the heap.<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">I think that,
              compared to C#'s "value-types", Java can take advantage of
              the fact that its value-class instances are immutable,
              which means that pass-by-value or pass-by-reference is
              indistinguishable, which, with nullable-inlined-values,<font size="4"> could mean that</font> Java can have the
              variable encoding-mode completely encapsulated/hidden from
              the user-model as a runtime implementation detail.<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">If this is
              possible, maybe Valhalla's Java could have a user-model
              like this:<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">*** A
              decomplected user-model ***<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">For
              class-authors:<br>
              <br>
               - *value-knob* to reject identity - Applicable on class
              declarations, indicates
              that the class instances don't require identity (a
              value-class).<br>
               - *zero-knob* to indicate that the value-class has a
              zero-value - if a value-class does not have a zero-value,
              its instances won't be inlined in any shared-variables
              (§17.4.1.) since this is the only way for the language to
              ensure the non-existence of the zero-value. If the
              value-class is declared with a zero-value, then care must
              be taken when reading/writing constructors since *no
              constructor invariant can exclude the zero-value*.<br>
               - *tearable-knob* to allow tearing - Applicable on zero
              value-class declarations with bitSize > 32 bits, may be
              used by the class-author to hand the class-user the
              responsibility of how to avoid tearing, freeing the
              runtime to always inline instances in shared-mutables
              (non-final shared-variables). Conversely, if this knob is
              not used, instances will be kept atomic, which allows the
              class-author to guarantee constructor invariants *provided
              they're not broken by the zero-value*, which may be useful
              for the class implementation and class-users to rely upon.<br>
              <br>
              For class-users:<br>
              <br>
               - *not-nullable-knob (!)* to exclude null from a
              variable's value-set - Applicable on any variable
              declarations. On nullable variables, the default value is
              null and, in either encoding-mode (reference or inline),
              the runtime is free to choose the encoding for the extra
              bit of information required to represent the null state.<br>
               - *atomic-knob* to avoid tearing - Applicable on
              shared-mutable declarations, may be used to reverse the
              effect of the tearable-knob, thereby restoring atomicity.</font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">The
              encoding-mode of a variable is decided at runtime
              according to this ternary expression:<br>
            </font></span></div>
        <div class="gmail_default"><span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)"><br>
              </span></font></span></div>
        <span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)"><span class="gmail_default" style="color:rgb(7,55,99)"></span>var encodingMode = <br>
                      !valueClass(variable.type)         ? REFERENCE   
              // value-knob<br>
                  :   tooBig(variable.type.bitSize)      ? REFERENCE<br>
                  :   !shared(variable)                  ? INLINE      
              // <span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>(§17.4.1.)<br>
                  :   !zeroValueClass(variable.type)     ? REFERENCE   
              // zero-knob<br>
                  :   final(variable)                    ? INLINE<br>
                  :   atomicWrite(variable.type.bitSize) ? INLINE<br>
                  :   atomic(variable)                   ? REFERENCE   
              // atomic-knob<br>
                  :   tearableValueClass(variable.type)  ? INLINE      
              // tearable-knob<br>
            </span></font></span>
        <div><span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)">    :
                                                       REFERENCE;<br>
              </span></font></span></div>
        <div><span style="font-family:monospace"><font size="4"><br>
              <span style="color:rgb(7,55,99)"></span></font></span></div>
        <div><span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)"></span></font></span></div>
        <span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)">The variable.type.bitSize
              depends on nullability as nullable types may require more
              space.<br>
              The predicates tooBig and atomicWrite depend on the
              hardware. <span class="gmail_default" style="color:rgb(7,55,99)">As an</span> example, they
              could be:<br>
              <br>
                  boolean tooBig(int bitSize)      {return bitSize >
              256;}<br>
                  boolean atomicWrite(int bitSize) {return bitSize <=
              64;}<br>
            </span><span style="color:rgb(7,55,99)"></span></font></span>
        <div><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)">Table-view of the user-model
              knobs:<br>
              <br>
              identity            ‖  (identity)
              |                          value                          
              |<br>
              zeroness            ‖  (no-zero)  |     (no-zero)   
              |                 zero                  |   <br>
              atomicity           ‖  (atomic)   |     (atomic)     |   
                (atomic)      |     tearable     |<br>
              nullability         ‖ <span class="gmail_default" style="color:rgb(7,55,99)"></span><span class="gmail_default" style="color:rgb(7,55,99)"> </span>(?)<span class="gmail_default" style="color:rgb(7,55,99)"></span>
              |  !   |  <span class="gmail_default" style="color:rgb(7,55,99)"> </span>(?)  |    !    | <span class="gmail_default" style="color:rgb(7,55,99)"> </span>(?)
              |      !      | <span class="gmail_default" style="color:rgb(7,55,99)"> </span>(?)<span class="gmail_default" style="color:rgb(7,55,99)"></span>
              |    !      |<br>
==============================================================================================<br>
              encoding-mode       ‖  reference  |                   
              inline/reference                      |<br>
              needs reference     ‖  everywhere | shared-variables |
              no/shared-mutables |        no        |<br>
              definite-assignment ‖  no  | yes  |   no   |   yes   | 
              no  |     yes     | yes  |    yes    |<br>
              default             ‖ null | n.a. |  <span class="gmail_default" style="color:rgb(7,55,99)"></span>null 
              |   n.a.  | null |     n.a.    | n.a. |    n.a.   |<br>
              init-default        ‖    null     |       null       |
              null |  zero/null  | null | zero/null |</span></font></span>
        <div class="gmail_default"><span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)"><br>
              </span></font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">Notes:<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)">
          <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> - tokens in
                parenthesis are the default when no knob is used<br>
              </font></span></div>
          <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> -
                definite-assignment (§16.) means that the compiler
                enforces <span style="font-family:monospace"><font size="4">(to the best of its ability) </font></span>variable
                initialization before usage</font></span></div>
          <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> - default is
                the default-value of a variable when not
                definitely-assigned<br>
              </font></span></div>
        </div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> - init-default
              is the default-value of a variable before any
              initialization code runs</font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> - on
              non-nullable zero value-classes, the init-default (zero or
              null) <span style="font-family:monospace"><font size="4">depends
                  on the </font></span>encoding-mode chosen by the
              runtime<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"> - on atomic
              zero value-classes, reference-encoding is needed on
              shared-mutables if instance bitSize cannot be written
              atomically<br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div class="gmail_default" style="color:rgb(7,55,99)">
          <div class="gmail_default" style="color:rgb(7,55,99)">
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">***
                  Migration of value-based classes ***<br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><span style="font-family:monospace"><font size="4"><br>
                    </font></span></font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><span style="font-family:monospace"><font size="4">Requiring
                      definite-assignment on all non-nullable
                      shared-mutables is useful to get rid of
                      missed-initialization-bugs, so I think it's a good
                      idea to require it wherever source-compatibility
                      allows.</font></span></font></span>
              <div class="gmail_default" style="color:rgb(7,55,99)">
                <div class="gmail_default" style="color:rgb(7,55,99)">
                  <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">In
                        this model, all value-based classes can be
                        migrated to (atomic) zero value-classes. Due to
                        definite-assignment, even if LocalDate is
                        migrated to a zero value-class, it will be hard
                        to get an accidental "Jan 1, 1970". Rational can
                        also be a zero value-class but users will have
                        to keep in mind that it's possible to get a
                        zero-denominator Rational, even if the
                        constructor throws when we try to build one.</font></span></div>
                </div>
              </div>
              <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">To
                    maintain source-compatibility, no migrated
                    value-based class can be tearable, not even Double
                    or Long, since wherever in existing code we have a
                    field declaration such as:<br>
                  </font></span></div>
              <span style="font-family:monospace"><font size="4"><br>
                      ValueBasedClass v;<br>
                  <br>
                  v is always reference encoded and, therefore, atomic.
                  For Double and Long, this is a bit of an anomaly,
                  because it means that for these two primitives, and
                  for them alone, each of these pair of field
                  declarations will not be semantically equivalent:<br>
                  <br>
                  long v;    // tearable <br>
                  Long! v;   // atomic</font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">double d; 
                  // tearable<br>
                  Double! d; // atomic<br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div class="gmail_default" style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">João
                  Mendonça<br>
                </font></span></div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>