<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">
<span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"></span>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.</font></span></div></div></blockquote><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><div><div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">The problem it's trying to solve is to remove the .val and .ref operators/knobs/concepts from the user-model without any loss of performance or loss of control over nullability, zeroness or atomicity. In other words, the objective is to take Kevin's ref-by-default idea one step
 further.</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><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">
<span class="gmail_default" style="color:rgb(7,55,99)"></span>In theory, we could construct the
        union type int|Null, but this type doesn't have a practical
        representation in memory, ...</font></span></div></blockquote><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 class="gmail_default" style="color:rgb(7,55,99)">Would it be possible to have a value-class give rise to these 3 hidden/runtime-only companion-types 
<font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"> on the heap</span></font>:</span></font></span><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><br></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">    RefType  - reference to a value-instance or no-reference (null)<br></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">    ValType  - inlined [value-instance-fields]<br></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">    ValType? - inlined [nullability-boolean +
<font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">value-instance-fields]</span></font></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><br></span></font></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">Then, the runtime could transparently choose between RefType|ValType for non-nullable variables or between RefType|ValType? for nullable variables, depending on hardware, bitSize, zeroness and atomicity constraints<font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">, as explained by the ternary expression in my previous email</span></font></span></font>. Of course, since ValType? has a higher bitSize than ValType, nullable values will be less likely to be inlined. But still, the point is: could nullable values sometimes be inlined on the heap as opposed to never being inlined.<br></span></font></span></font></span></div><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)"></span></font>

</span></font></span></div><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><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><span style="font-family:monospace"><font size="4"><span class="gmail_default" style="color:rgb(7,55,99)">
<span class="gmail_default" style="color:rgb(7,55,99)"></span>In theory, we could construct the
        union type int|Null, but this

(...) drags in all sorts of mismatches
        because union types would then flow throughout the system.

</span><br></font></span></div></blockquote><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><div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"></span></div><div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">Is my 3-companion-types solution a real union type? Sure, I am suggesting two sort-of-unions:</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">    RefType|ValType  - for non-nullable value-class variables<br></font></span></div><div style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">    RefType|ValType? - for nullable value-class variables<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 style="color:rgb(7,55,99)" class="gmail_default"><span style="font-family:monospace"><font size="4">However, to the user, both types in each union represent the same exact value-set.<br></font></span></div><div><font size="4"><span style="font-family:monospace"> <span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span></span></font></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 1 Jul 2022 at 00:55, Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

  
  <div>
    <font size="4"><font face="monospace">From the -comments list.  <br>
        <br>
        <span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>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)"><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.)  <span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span><span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>In theory, we could construct the
        union type int|Null, but this type doesn't have a practical
        representation in memory, and <span class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"></span>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 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><br>
      <br>
      -------- Forwarded Message --------
      <table cellspacing="0" cellpadding="0" border="0">
        <tbody>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Subject:
            </th>
            <td>nullable-inlined-values on the heap</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Date: </th>
            <td>Thu, 30 Jun 2022 23:02:17 +0100</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">From: </th>
            <td>João Mendonça <a href="mailto:jf.mend@gmail.com" target="_blank"><jf.mend@gmail.com></a></td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">To: </th>
            <td><a href="mailto:valhalla-spec-comments@openjdk.org" target="_blank">valhalla-spec-comments@openjdk.org</a></td>
          </tr>
        </tbody>
      </table>
      <br>
      <br>
      
      <div dir="ltr">
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">Hello,</font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div 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 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">*** A
              decomplected user-model ***<br>
            </font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div 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><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>|<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><span style="font-family:monospace"><font size="4"><span style="color:rgb(7,55,99)"><br>
              </span></font></span></div>
        <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">Notes:<br>
            </font></span></div>
        <div style="color:rgb(7,55,99)">
          <div 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 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 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 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 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 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
            </font></span></div>
        <div style="color:rgb(7,55,99)">
          <div style="color:rgb(7,55,99)">
            <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4">***
                  Migration of value-based classes ***<br>
                </font></span></div>
            <div 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 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 style="color:rgb(7,55,99)">
                <div style="color:rgb(7,55,99)">
                  <div 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 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div 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 style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div style="color:rgb(7,55,99)"><span style="font-family:monospace"><font size="4"><br>
                </font></span></div>
            <div 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>
  </div>

</blockquote></div></div>