B3, default values, and implicit initialization
Brian Goetz
brian.goetz at oracle.com
Fri Apr 21 19:49:50 UTC 2023
Over on the -comments list, Quân Anh Mai suggested drawing inspiration
from the C++ term, "trivially default constructible", which is tied to
the act of construction. Its a bit wordy but "default constructible" is
probably a reasonable term, and ties to the under-consideration syntax of
default Foo();
as a constructor. "Trivially constructible" is also a reasonable term
if we end up selecting a different syntax for the final expression.
On 4/20/2023 6:27 PM, Brian Goetz wrote:
> 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:
>
> - The author of a class, who is making a decision about whether the
> zero state represents a sensible default.
> - 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.
> - The specification / descriptive documents, which will need a way to
> talk about "classes that are friendly to uninitialized use."
>
> This concept is made more difficult because this property will only
> have observable effects for variables with null-restricted types.
>
>
>
>
>
>
>
> On 3/28/2023 3:13 PM, Brian Goetz wrote:
>> 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.
>>
>> 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.)
>>
>> 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.)
>>
>> 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.
>>
>> 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.
>>
>> Framed this way, the Valhalla performance story simplifies to:
>>
>> - Give up identity, get flattening on the stack;
>> - Further give up explicit initialization, get flattening for small
>> objects on the heap;
>> - Further give up atomicity, get flattening for larger objects on
>> the heap.
>>
>> Giving up explicit initialization entails both the class opting out
>> of explicit initialization, _and_ the variable opting out of nullity.
>>
>> The key new terminology that comes out of this is implicit vs
>> explicit initialization.
>>
>>
>> Syntactically, my preference is to indicate that the default value
>> can be summoned by giving a value class a _default constructor_:
>>
>> value class Complex {
>> public final double re, im;
>>
>> public default Complex();
>> }
>>
>> 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.
>>
>> 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.
>>
>> 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.)
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-experts/attachments/20230421/a6037331/attachment-0001.htm>
More information about the valhalla-spec-experts
mailing list