<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">Hello again,</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">Pondering a bit more on Tim Feuerbach's fine analysis of the current state of the discussion concerning the illegal zeros leak problem, has made me reconsider its effects on the user-model I had suggested in my "no-subject" email:</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">*Inlining  in shared-variables (§17.4.1.) makes it impossible to hide the zero-value*</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">therefore:</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">*No constructor invariant of a value-class can exclude the zero-value*<font face="verdana,sans-serif"><br></font></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><font face="verdana,sans-serif"><br></font></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><font face="verdana,sans-serif">This is actually bad. It seems to me that most Records are effectively value-based classes<span>, and</span></font><font face="verdana,sans-serif"><span> I was thinking that it would be nice to make them value-classes, not for the inlining, but to clearly express the intended semantics and get help from the compiler/runtime to avoid bugs, such as synchronizing on them or comparing their identity.</span></font><font face="verdana,sans-serif"><span></span><span> This is a problem for the user-model I had suggested, because all these Records are <font face="verdana,sans-serif">filled with <span>"requireNonNull" in their constructors (using "!" is the same), and</span></font> having to keep in mind that none of this can really be trusted upon is just awful.</span><br></font></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">So, biting the bullet, how about this user-model:<br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">For class-authors:<br><br> - *value-knob* to reject identity - Applicable on class declarations. Used by a class-author to indicate 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 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, 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 declaration. *All non-nullable shared-mutables must be definitely-assigned*. For nullable variables, the default value is null and, in either encoding-mode, the runtime is free to choose the encoding for the extra bit of information required to represent whether or not a variable is null.<br> - *atomic-knob* to avoid tearing - Applicable on shared-mutable declarations, may be used by the class-user to reverse the effect of the tearable-knob, thereby restoring atomicity.</div><br><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">Requiring definite-assignment to all non-nullable shared-mutables is 
useful to get rid of missed-initialization-bugs. As Tim explained to me, to initialize 
non-nullables with zero-values we can assign the constant ValueClass.zero or
the array constructor new ValueClass.zero[size] which can be optimized 
away by the compiler. <br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><div class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)">In
 this model, all value-based classes are migrated to (non-tearable) zero value-classes. So, even though LocalDate is a zero 
value-class, due to definite-assignment, it will be very 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.</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)">Most Records, on the other hand, will be (no-zero) value-classes, making all their constructor invariants always reliable. They won't be inlined in shared-variables but, due to their big size, most wouldn't be anyway.</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)"><br></div></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">The runtime chooses the encoding-mode of a ClassType variable according to this ternary expression:<br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">var encodingMode = <br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   !valueClass(variable.type) ? REFERENCE</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   tooBig(variable.type.bitSize) ? REFERENCE</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">// Illegal zeros:<br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   !shared(variable) ? INLINE</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   !zeroValueClass(variable.type) ? REFERENCE</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">// Atomicity:<br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><div class="gmail_default" style="font-family:verdana,sans-serif;color:rgb(7,55,99)">    :   final(variable) ? INLINE</div>    :   atomicWrite(variable.type.bitSize) ? INLINE</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   atomic(variable) ? REFERENCE    // atomic-knob<br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    :   tearableValueClass(variable.type) ? INLINE<br>    :   REFERENCE;</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">The variable.type.bitSize changes with nullability i.e. a nullable type will have a higher bitSize due to the extra bits required to also represent null.</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">The predicates tooBig and atomicWrite depend on the hardware specs. For example, on my laptop they could be (written in the "Concise Method Bodies" style):</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    boolean tooBig(int bitSize) -> bitSize>256;</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">    boolean atomicWrite(int bitSize) -> bitSize<=64;</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">João Mendonça</div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763"></div><div class="gmail_default" style="font-family:verdana,sans-serif;color:#073763">PS: I realize that, probably, all of this has been analyzed and discussed to death during the past 7 years in this mailing list, and I, for only having learned a tiny bit of it, am just making a fool out of myself with all these silly suggestions. If that is the case, please let me know and I apologize in advance for wasting your time.</div></div>