Value types design decisions
Brian Goetz
brian.goetz at oracle.com
Sun Jan 21 20:52:03 UTC 2024
This is something that we are actively exploring now, but haven't yet
settled on a treatment of. Though null-retricted != inlined (e.g.,
String![]). We can always treat LocalDate![] the same as String![], but
we'd like to do better. Here, there are higher requirements to
initialize-before-possible-use.
An assignment of null to an Anything![] element will result in an
NPE/ASE (just as today assigning an Integer to an element of a String[]
cast to Object[].) So invalid-values-on-write are handled.
On 1/21/2024 12:20 AM, - wrote:
> Hi Brian, from your description of LocalDate![] comes a contingent
> question:
> Can (non-implicitly constructable) classes now have null-restricted
> (inlined) fields of types that are not implicitly constructable, given
> these fields will be initialized by the constructors to valid values?
> I assume any assignment of invalid values (notably, null) will simply
> result in exceptions such as NPE.
>
> If yes, how will such fields be represented in heap as:
> 1. identity object's final fields?
> 2. identity object's mutable fields?
> 3. non-implicitly constructable value object's final fields?
>
> Given these fields can have their proper states visible no later than
> their owner objects are visible.
>
> I think this is a new aspect of inlining that hasn't yet been
> discussed, but is probably worth discussing.
>
> Regards,
> Chen Liang
>
> On Sat, Jan 20, 2024 at 2:17 PM Brian Goetz <brian.goetz at oracle.com>
> wrote:
>
> This interacts with nullity control. If a variable is nullable,
> its default value is null -- end of story. But nullability is
> often (not always) an impediment to flattening. So if you want a
> flat field / array, you probably are using a non-nullable
> field/component type. Of the three kinds (identity (String),
> implicitly constructible value (Integer),
> non-implicitly-constructible value (LocalDate)), we get three
> different stories about flattening and failure modes:
>
> String![] -- these will never be flattened, so the default value
> of elements is still null. We have some design choices about
> whether to make "good faith efforts" for preventing these from
> being published before being fully ininitialized, but if one does
> escape, the downside is not terrible -- an unexpected NPE, but no
> loss of integrity.
>
> Integer![] -- these can get flattened routinely, and it's
> perfectly fine to publish an array whose elements are
> uninitialized, because Integer is implicitly constructible, which
> means the default value is just fine.
>
> LocalDate![] -- We can flatten these only if we have 100% ironclad
> proof that every element has been initialized to a valid value
> prior to publication. Allowing the zero to escape undermines a VM
> integrity promise, and this can never happen.
>
> As to "how would this work", design discussions are ongoing, stay
> tuned.
>
>
> On 1/20/2024 2:41 PM, David Alayachew wrote:
>> Hello Brian,
>>
>> Just wanted to ask about this point below.
>>
>> > These two examples (conveniently, from the same package)
>> > tell us a truth about modeling data with value objects:
>> > some classes have reasonable defaults (and we can exploit
>> > this to optimize their treatment, and can freely let
>> > people use uninitialized variables, as we do for
>> > primitives today), and some do not (and hence we need
>> > either to engage nullability, or work very hard to ensure
>> > that an object cannot possibly be used uninitialized.
>>
>> Oh woah, what does it look like to prevent an object to be used
>> uninitialized? We don't have any compiler-enforced ways of doing
>> this, right? You are talking about just manually code reviewing
>> each use of the class to try and hope to catch any misuse?
>>
>> And if you mean manual review, is that really something that
>> would be worth the effort? Aside from the most trivial
>> situations, I can't think of an example.
>>
>> Thank you for your time and help!
>> David Alayachew
>>
>> On Sat, Jan 20, 2024 at 2:23 PM Brian Goetz
>> <brian.goetz at oracle.com> wrote:
>>
>> Forgot to address this part.
>>
>> On 1/20/2024 2:00 AM, Smith Wilson wrote:
>> > It could solve problems with such classes like LocalDate
>> which require
>> > more special zeroInstance (1970-1-1) than value with pure
>> defaults.
>>
>> The key thing to realize about LocalDate is that while it is
>> a good
>> candidate for being a value type, there is *literally no*
>> good default
>> value. Jan 1 1970 is not a good default value, as we've all
>> seen by
>> getting emails that tell us our subscriptions are going to
>> expire 54
>> years ago. No other specific date is a good default either.
>> This is a
>> statement about the _domain_; there is no good default. (And
>> when an
>> abstraction does not have a good default, null is your friend.)
>>
>> Other classes have good defaults; Duration is such an example.
>>
>> These two examples (conveniently, from the same package) tell
>> us a truth
>> about modeling data with value objects: some classes have
>> reasonable
>> defaults (and we can exploit this to optimize their
>> treatment, and can
>> freely let people use uninitialized variables, as we do for
>> primitives
>> today), and some do not (and hence we need either to engage
>> nullability,
>> or work very hard to ensure that an object cannot possibly be
>> used
>> uninitialized.
>>
>> The reason that "implicit constructor" is a thing is that,
>> even after
>> we've identified that a class is a value class, we still have to
>> identify something else: whether it is implicitly
>> constructible or
>> requires explicit construction. (There's other ways to frame
>> it, of
>> course, but the key is that this has to be in the programming
>> model.)
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20240121/076389d5/attachment.htm>
More information about the valhalla-dev
mailing list