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