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