<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>