<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<br>
<blockquote type="cite" cite="mid:CAGKkBkttZ35rvuZ7Exfe6Ozh1CJS0NSmTFKMrQ-K+sW1N_66Vg@mail.gmail.com">
<div dir="ltr">
<div>All else being equal, the idea to use "inaccessible value
type" over "value type doesn't exist" feels very good and
simplifying, with the main problem that the syntax can't help
but be gross.</div>
</div>
</blockquote>
<br>
Yep.<br>
<br>
<blockquote type="cite" cite="mid:CAGKkBkttZ35rvuZ7Exfe6Ozh1CJS0NSmTFKMrQ-K+sW1N_66Vg@mail.gmail.com">
<div dir="ltr">
<div>* It feels wrong to restrict access to the type only
because of two very specific things we don't want people to do
with the type. We don't want them to write `new
TheType.val[size]`, and we don't want them to write
`TheType.val someUnintializedField;`. Is there a third? And
can we really not just prevent those specific things? It feels
like baby/bathwater, especially since delayed initialization
scenarios like those are already problematic in many ways as
it is.</div>
</div>
</blockquote>
<br>
This is where I started; that the thing really being protected
against is _creating heap locations with their default value_, which
is done by fields and by array creation expressions. (When we get
to specializable generics, there will be a third: using the .val
class as a type parameter, since `Foo<T>` might have
uninitialized T-valued fields, so a `Foo<P.val>` could have
the same problem as any other class that declares a `P.val` field.)
<br>
<br>
The reason I backed off is that this seemed (a) a hard border to
explain, (b) calling users attention to low-level details like heap
vs stack values, and (c) the value of being able to use P.val
here-but-not-there is not all that strong. <br>
<br>
Hard to explain. Understanding this requires understanding a lot of
low-level things that many Java developers have never thought about,
such as heap vs stack, or the fact that, even if a static field has
an initializer, you can still observe its default value with unlucky
timing. Drawing the border to keep the zeroes out will require a
lot of context, focus on details we would rather users not dwell on,
and will invariably be perceived as a "weird" restriction. Whereas
"this type is private, you can't see it" seems pretty normal. <br>
<br>
Small incremental benefit. This one requires appealing to the
low-level details, but basically, the benefit of using P.val instead
of P.ref in stack contexts (method parameter and returns, locals)
appears to be pretty small, because of the excellent calling
convention optimization that we get even on (preloaded) L-types of
value classes. The jury is out on "appears", but it is looking that
way. So the argument of "don't sweat the difference between P.ref
and P.val except in the heap" seems reasonable. \<br>
<br>
Similarly, if P wants to, it can dispense safely constructed
instances of P.val[], which are covariant to the exported P.ref[].
<br>
<br>
So this felt like a reasonable "worse is better" move, but I'm open
to new ideas.<br>
<br>
<blockquote type="cite" cite="mid:CAGKkBkttZ35rvuZ7Exfe6Ozh1CJS0NSmTFKMrQ-K+sW1N_66Vg@mail.gmail.com">
<div dir="ltr">
<div>* I still am saddled with the deep feeling that ultimate
victory here looks like "we don't need a val type, because by
capturing the nullness bit and tearability info alone we will
make <i>enough</i> usage patterns always-optimizable, and we
can live with the downsides". To me the upsides of this
simplification are enormous, so if we really must reject it, I
may need some help understanding why. It's been stated that a
non-null value type means something slightly different from a
non-null reference type, but I'm not convinced of this; it's
just that sometimes you have the technical ability to conjure
a "default" instance and sometimes you don't, but nullness of
the type means what it means either way.</div>
</div>
</blockquote>
<br>
Here's the chain of reasoning that works to get to this state of
affairs. <br>
<br>
- Reference types don't tear. The JMM gives us strong safety
guarantees about references to objects with final fields. We want
this to work the same way for references to value objects as well as
references to identity objects, because otherwise, the "immutability
means thread safety" promise is undermined. <br>
<br>
- P.ref is a reference type; P.ref[] is an array of references. <br>
<br>
- For non-atomic value classes, P.val fields can tear under race
(and similarly elements of P.val[]). <br>
<br>
- If we spelled .val as !, then switching from P[] to P![] not only
prohibits null elements, but changes the layout and _introduces
tearing_. Hiding tearability behind "non-null" is likely to be a
lifetime subscription to Astonishment Digest, since 99.9999 out of
100 Java developers will not be able to say "non-null, oh, that also
means I sacrifice atomicity." <br>
<br>
The link you probably want to attack is this last one, where you are
likely to say "well, that's what you opted into when you said
`non-atomic`; you just happen to get atomicity for free with
references, but that's a bonus." <br>
<br>
<br>
</body>
</html>