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