Value type companions, encapsulated
Clement Cherlin
ccherlin at gmail.com
Thu Aug 4 21:37:26 UTC 2022
On Mon, Jul 25, 2022 at 7:29 AM John Rose <john.r.rose at oracle.com> wrote:
>
> In this message Brian wrote out the major features
> of an emerging design for value classes:
>
> From: Brian Goetz brian.goetz at oracle.com
> To: … valhalla-spec-experts at openjdk.java.net
> Subject: Re: User model stacking: current status
> Date: Thu, 23 Jun 2022 15:01:24 -0400
>
> I think controlling the complexity by having a separate
> nested declaration of the value companion type will
> work very well.
>
> So what exactly does a private value companion do?
> What is it you can and cannot do with this type?
> What problems are prevented by privatizing it?
> How and when is privatization enforced?
> What other problems are created by those new rules?
>
> I have been pulling on this thread for a few days
> now, and I think I have some answers.
>
> http://cr.openjdk.java.net/~jrose/values/encapsulating-val.md
> http://cr.openjdk.java.net/~jrose/values/encapsulating-val.html
>
> (The Hitchhiker’s Guide suddenly comes to mind. Don’t panic!)
>
> I expect I will be editing these files as we go.
> For reference here is a verbatim copy of the MD file
> as it stands right now (minus the header):
>
[snipped]
After reading most of this proposal, I have a few thoughts.
The "encapsulated .val" design requires a tremendous amount of JVM
machinery; non-denotable types; and exacting care from class authors to
prevent zero values from escaping.
I propose a simpler, more robust design.
Every `non-zero flattened` class has a default value, chosen by the class
author in one of the following ways:
1. A constant expression which is stamped in the class file and copied bit
for bit by the JVM.
2. A non-constant static method which runs once at class loading time, the
result of which is thereafter copied bit for bit by the JVM.
There are far fewer problems safely constructing value objects than
identity objects because value objects can't have super constructors, all
fields are final, and if necessary, default value constructors can be
constrained (similar to canonical record constructors) to have limited
access to `this`.
Rule: When creating an array or heap-allocated object that contains one or
more `non-zero flattened` elements/fields, all `non-zero flattened`
elements/fields must be pre-initialized by the JVM. If an explicit value is
not provided, the class's default value is used. For heap-allocated
objects, this pre-initialization must be performed before calling <init>.
For arrays, this pre-initialization must complete before the array is
published. If a heap-allocated object's <init> wants to initialize a
`non-zero flattened` field with a dynamically computed value, it will need
to overwrite the constant, pre-initialized value. This is no different from
having to overwrite the pre-zeroed primitive/null values in an identity
class constructor.
While this proposal requires a modest amount of JVM and verification
machinery to ensure zero-safety, that machinery is localized to the nuts
and bolts of creating heap-allocated instances and arrays. There is no need
to perform extensive visibility or permissions checks, it avoids a new
"companion" keyword, and all the class author needs to do is write a simple
default declaration.
Note that the machinery to ensure heap-allocated instances and arrays of
`non-zero flattened` classes is *still required* in the "encapsulated .val"
world, but must be repeated by the authors of every individual `non-zero
flattened` class in perpetuity, instead of being implemented correctly,
once, in the JVM.
Cheers,
Clement Cherlin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220804/32bbcbdd/attachment.htm>
More information about the valhalla-spec-observers
mailing list