<div dir="ltr">Turning in my homework late because I don't have a good answer for where to specify the "non-atomic" modifier and have minor misgivings about reusing the term "default".<div><br></div><div>Despite my initial concerns with the default constructor (primarily how easily a consumer of a class can find this property), I've come around to the "public default Complex()" constructor model because it clearly lets a class's author indicate their intent. The default constructor should appear as a method in the classfile, though without a Code_attribute, and should be visible to reflection, etc. It's a constructor like any other which also acts as a flag to indicate the author accepts the all-zeros pattern. Expressing this through the constructor is a clean approach for users and let's us build on existing infrastructure for representing it - similar to how interface default methods benefited from being modeled as regular methods.</div><div><br></div><div>Discoverability can be handled by having the javadoc for class report the default constructor (like any other constructor) which handles most consumers. Those reading the source can either search for "default" keyword or be helped by their IDE to flag the classes in some way.</div><div><br></div><div>My misgivings around the term "default" are due to having already used it to describe interface methods with a default implementation. The term has also been used related to the default (initial) value of variables but that has no syntax associated with it. So precedent supports its use..... a mixed result I guess? ....And I just found a section in the JLS (8.8.9) that already defines the default constructor for a class. That's even stronger precedent for reusing the term here given this is a slightly different kind of default constructor.</div><div><br></div><div>We've previously talked about allowing value classes to extend abstract classes. What are the conditions that would allow my value class to implement a default constructor if it extends an abstract class? Would the abstract class need a default constructor? No constructor? (Probing for the edges of this model to see if it breaks down)</div><div><br></div><div> I really wanted to cram the non-atomic designation on constructors as well but it's not really a property of the instance; rather it describes writes to storage which puts it as a property of the class. Still trying to come up with a better intuition for where this belongs.</div><div><br></div><div>--Dan</div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 20, 2023 at 6:27 PM 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">As I mentioned yesterday, the
high order bit here is how we describe a class whose
(null-restricted) instances can tolerate (and possibly even
encourage) uninitialized use, just as the primitives do today.
Ignoring the surface syntax, what we really need is an evocative
term for such a class. This term has to be useful and evocative
to multiple participants:<br>
<br>
- The author of a class, who is making a decision about whether
the zero state represents a sensible default. <br>
- The client of a class, who may exploit the fact that
instances may be safely used uninitialized, or who may want to
reason about flattening. <br>
- The specification / descriptive documents, which will need a
way to talk about "classes that are friendly to uninitialized
use." <br>
<br>
This concept is made more difficult because this property will
only have observable effects for variables with null-restricted
types. <br>
<br>
<br>
<br>
<br>
<br>
<br>
</font></font><br>
<div>On 3/28/2023 3:13 PM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite">
<font size="4"><font face="monospace">The recent update of JEP 401
contained a number of refinements to the user model,
specifically, separating the primitive/reference distinction
into a number of smaller distinctions (e.g., nullable vs
non-nullable, optional vs required construction.) Overall
this has been a very positive step forward. <br>
<br>
We still have a need for the distinction between what we've
been calling B2 and B3; JEP 401 currently frames that in terms
of "construction is optional." This is a big step forward;
indeed, the key difference between them is whether the class
_needs_ the "variables start out as null, and all instances
are created by constructors" protection, or whether it admits
the lighter-weight initialization protocol of "there's a a
standard zero value, null-free variables are initialized to
that" that primitives enjoy today. (Note that B3 classes
don't require this lighter protocol, they merely enable it,
much as primitives all give you the option of boxing to get
the full conservative initialization protocol.)<br>
<br>
The idea of framing this as "construction is optional" is a
good one, but the expression of it proposed in JEP 401 feels
"not quite there". In this note I'll propose an alternative
presentation, but the main goal here is around terminology and
user model rather than syntax (so please keep the syntax
agitation to a reasonable level.)<br>
<br>
The key distinction between B2 and B3 is that B3 has a
_default value_ which the VM can summon at will. This enables
non-nullable heap variables to be flattened, because we can
initialize these the same way we initialize other fields and
array elements. Further, that default value is highly
constrained; it is a physical zero, the result of initializing
all fields to their default value. <br>
<br>
Flattening is of course a goal, but it is not something that
exists in the programming model -- its just an optimization.
What exists in the programming model is the default value, and
what this unlocks is the possibility for variables to be
_implicitly initializated_. Reference-typed variables today
are _explicitly initialized_; variables start out null and
have to be initialized with a constructed value. A class with
a default value has the option (opted in through
null-exclusion) for its variables to be implicitly
initialized, which, like primitives, means that they start out
with a valid default value, and can be further assigned to. <br>
<br>
Framed this way, the Valhalla performance story simplifies to:<br>
<br>
- Give up identity, get flattening on the stack;<br>
- Further give up explicit initialization, get flattening for
small objects on the heap;<br>
- Further give up atomicity, get flattening for larger
objects on the heap.<br>
<br>
Giving up explicit initialization entails both the class
opting out of explicit initialization, _and_ the variable
opting out of nullity. <br>
<br>
The key new terminology that comes out of this is implicit vs
explicit initialization. <br>
<br>
<br>
Syntactically, my preference is to indicate that the default
value can be summoned by giving a value class a _default
constructor_:<br>
<br>
</font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace"> value class Complex { <br>
public final double re, im;<br>
<br>
public default Complex();<br>
}<br>
</font></font><br>
A default constructor has no arguments, no body, no throws
clause, and implicitly initializes all fields to their default
values. Unlike identity classes, value classes don't get
constructions implicitly; a value class must declare at least
one constructor, default or otherwise. This replaces the idea
of "optional constructor", which is a negative statement about
construction ("but you don't have to call me"), with a more
direct and positive statement that there is a _default
constructor_ with the required properties. <br>
<br>
Note that this is similar to the existing concept of "default
constructor", which you get for free in an identity class if
you don't specify any constructors. It is possible we can
unify these features (and also with constructors in "agnostic"
abstract classes), but first let's work out what it would mean
in value classes, and see if we like it.<br>
<br>
In this model, a B3 class is just a value class with a default
constructor -> a default constructor means that you have
the choice of implicit or explicit initialization ->
non-nullity at the use site opts into implicit initialization
-> B3! gets flattening (for small layouts.) <br>
<br>
<br>
</font></font> </blockquote>
<br>
</div>
</blockquote></div>