On Tue, Jun 14, 2022 at 9:17 AM Brian Goetz <brian.go...@oracle.com> wrote:
>
>
> The val type for B2 should not exist at all
>
>
>
> So B2 is really a B3a whose value projection is encapsulated.
>
>
> and here you lost me, .ref and .val are supposed to be projection types not 
> classes, at runtime there is only one class.
>
>
> And apparently I have to say this again .... It's fine to not understand what 
> is being proposed.  If so, ask questions, or think about it for a few days 
> before responding.  But it's Not OK to jump to dogmatic "should not" / 
> "wrong" pronouncements before you understand what is being proposed.  That's 
> just unhelpful.
>
>
>
> Summary:
>
>     class B1 { }
>     value class B2 { private class val { } }
>     value class B3a { }
>     non-atomic value class B3n { }
>
> Value class here is clearly the star of the show; all value classes are 
> treated uniformly (ref-default, have a val); some value classes encapsulate 
> the val type; some value classes further relax the integrity requirements of 
> instances on the heap, to get better flattening and performance, when their 
> semantics don't require it.
>
> It's an orthogonal choice whether the default is "val is private" and "val is 
> public".
>
>
> It makes B2.val a reality, but B3 has no sane default value otherwise it's a 
> B3, so B2.val should not exist.
>
>
> Let me try explaining again.
>
> All value types have .ref and .val types.  They have the properties we've 
> been discussing for a long time: ref types are references, and are therefore 
> nullable and atomic; val types are direct values, are not nullable, and are 
> _not necessarily_ atomic.
>
> We've been describing B2 classes as those with "no good default", but that 
> doesn't mean that they can't have a .val type.  It means we *can't trust 
> arbitrary code to properly initialize a B2.val type.*   Once initialized, 
> B2.val is fine, and have the benefit of greater flatness.  We explored 
> language and VM features to ensure B2.val types are properly initialized, but 
> that ran into the rocks.
>
> But we can allow the B2 class itself to mediate access to the .val type.  
> This has two benefits:
>
>  - We can get back some of the benefit of flattening B2.val types
>  - Uniformity
>
> Here are two examples of where a B2 class could safely and beneficially use 
> B2.val:
>
>      value class Rational {
>           Rational[] harmonicSeq(int n) {
>               Rational.val[] rs = new Rational.val[n];
>               for (int i=0; i<n; i++)
>                   rs[i] = new Rational(1, n);
>               return rs;
>           }
>      }
>
> Here, we've made a _flat_ array of Rational.val, properly initialized it, and 
> returned it to the user.  THe user gets the benefit of flatness, but can't 
> screw it up, because of the array store check.  If Rational.val were illegal, 
> then no array of rationals could be flat.

And with Rational.val requiring atomic access, we can only flatten it
if the underlying HW supports it (in this case, 2 ints fits nicely in
64bits so we're good).  Larger .val's can only be flattened if marked
as "non-atomic" (the B3n case).  And because there's no tearing,
handing out the flattened Rational.val[] is safe.

Do I have that right?

--Dan

>
> Similarly, a nestmate could take advantage of packing:
>
>     value class Complex {
>         value class C3 {
>             Complex.val x, y, z;
>
>             ...
>         }
>
>         C3 c3(Complex x, Complex y, Complex z) { return new C3(x, y, z); }
>
>     }
>
> C3 gets the benefit of full flattening, which it can do because its in the 
> nest; it can share the flattened instances safely with code outside the nest.
>
> (Access control is powerful thing.)
>
>

Reply via email to