Value types design decisions
-
liangchenblue at gmail.com
Sun Jan 21 05:20:39 UTC 2024
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/20240120/08459ce3/attachment.htm>
More information about the valhalla-dev
mailing list