<div dir="ltr"><div>I'm sympathetic to some of this. But I think I can accept the stake Brian is putting in the ground. He says: a concrete class should be empowered to provide for its own integrity, not merely count on its users to not hold it wrong. If we must preserve that, then okay, we must.</div><div><br></div><div>I worry about decision fatigue for common cases, but I'm optimistic we have a really good story here now:</div><div><br></div><div>1. First you will decide whether your class is a value class. I think this should be as simple as "do you need any of the features identity would provide?"</div><div>2. Then you will decide how much you want to expose its value companion type. Is this as simple as "does it feel worth the (nonzero) risk of bogus uninitialized instances floating around?"</div><div>3. And, if you know what you're doing, and you really need to optimize heavily, you can make it non-atomic.</div><div><br></div><div>So I disagree with the main request (always-public companion types), but I have a few comments/questions on the details.</div><div><br></div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jun 30, 2022 at 7:15 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><div dir="ltr" class="gmail_attr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

  
  <div><font size="4"><font face="monospace">Your Accumulator example is correct, but I think you are
        overestimating the novelty of the problem.  Arrays have always
        had a dynamic check; I can cast String[] to Object[] and hand
        that to you, if you try to put an Integer in it, you'll get an
        ASE.  Handing out arrays for someone else to write to should
        always specify what the bounds on those writes are; "don't write
        nulls" is novel in degree but not in concept. </font></font></div></blockquote><div><br></div><div>It is quite rare for public APIs to exchange arrays for purposes of writing to them. It's a code smell. The safe and conscientious practice since the beginning has been to only write to arrays you created yourself. I agree with Brian that there's not much new here.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font size="4"><font face="monospace"><blockquote type="cite">3. Let the compiler treat fields of
          companion-types like final fields today, i.e. enforce
          initialization. </blockquote>
        If this were possible to do reliably, we would have gone this
        way.  But initializing final fields today has holes where the
        null is visible to the user, such as class initialization
        circularity and receiver escape.  (And a reliable protocol is
        even harder for arrays.)  Exposing a null in this way is bad,
        but exposing the zero in this way would be worse, because now
        every user has a way to get the zero and inject it into
        unsuspecting (and unguarded) implementation code. </font></font></div></blockquote><div><br></div><div>I'd still like to understand what steps we can take to reduce the damage here, even if they're not 100% solutions.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font size="4"><font face="monospace"> There is
        simply no way we can reasonably expect everyone to write
        perfectly defensive code against a threat they don't fully
        understand and believe to be vanishingly rare -- and this is a
        perfect recipe for tomorrow's security exploits.  <br>
        <br>
        <blockquote type="cite">4. Provide the users with a convenient
          API for creating arrays with all elements initialized to a
          specific value.</blockquote>
        <br>
        We explored this as well; it is a good start but ultimately not
        flexible enough to be "the solution".  If a class has no good
        default, what value should it initialize array elements to? 
        There's still no good default.  And the model of "here's a
        lambda to initialize each element" is similarly an 80%
        solution. </font></font></div></blockquote><div><br></div><div>fwiw, I'll still keep pushing on offering these, if I can somehow. I think it's strange that they (create-and-fill, create-and-setAll) never got added to Arrays by now. It is very nice when the user can isolate themselves from the initialization gap.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font size="4"><font face="monospace">The goal here is to let people write classes that can be used
        safely.  If non-initialization is an mistake then we can make
        that mistake impossible.  That's much better than trying to
        detect and recover from that mistake.  <br>
        <br>
        <br>
      </font></font>
    <div><br>
      <br>
      -------- Forwarded Message --------
      <table cellspacing="0" cellpadding="0" border="0">
        <tbody>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Subject:
            </th>
            <td>Please don't restrict access to the companion-type!</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">Date: </th>
            <td>Thu, 30 Jun 2022 09:33:42 +0200</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">From: </th>
            <td>Gernot Neppert <a href="mailto:mcnepp02@googlemail.com" target="_blank"><mcnepp02@googlemail.com></a></td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap align="RIGHT">To: </th>
            <td><a href="mailto:valhalla-spec-comments@openjdk.java.net" target="_blank">valhalla-spec-comments@openjdk.java.net</a></td>
          </tr>
        </tbody>
      </table>
      <br>
      <br>
      
      <div dir="ltr">
        <div>I've been following the valhalla-development for a very
          long time, and have also posted quite a few comments, some of
          them raising valid concerns, some of them proving my
          ignorance.</div>
        <div><br>
        </div>
        <div>This comment hopefully falls into the first category: <br>
        </div>
        <div><br>
        </div>
        <div>My concern is that allowing access-restriction for a
          value-type's "companion-type" is a severe case of "throwing
          the baby out with the bathwater".</div>
        <div><br>
        </div>
        <div>Yes, I know what it is supposed to achieve: prevent users
          from accidentally creating zero-initialized values for
          value-types "with no resonable default".</div>
        <div><br>
        </div>
        <div>However, the proposed solution of hiding the companion-type
          will force programmers to use the reference-type even if they
          do not want to.</div>
        <div>Please have a look at the following class "Accumulator". It
          assumes that "Sample" is a value-class in the same package
          with a non-public companion-type.</div>
        <div>The Javadoc must now explicitly mention some pitfalls that
          would not be there if "Sample.val" were accessible.</div>
        <div>Especially the necessary precaution about the returned
          array-type is rather ugly, right?!</div>
        <div><br>
        </div>
        <div>public class Accumulator {</div>
        <div>   private Sample.val samples;<br>
        </div>
        <div><br>
        </div>
        <div>/**</div>
        <div>Yields the samples that were taken.<br>
        </div>
        <div>Note: the returned array is actually a "flat" array! No
          element can be null. While processing this array, do not try
          to set any of its elements to null, as that may trigger an
          ArrayStoreException!</div>
        <div>*/<br>
        </div>
        <div>public Sample[] samples() {</div>
        <div>    return samples.clone();<br>
        </div>
        <div>}<br>
        </div>
        <div>}</div>
        <div><br>
        </div>
        <div>To sum it up, my proposal is:</div>
        <div><br>
        </div>
        <div>1. Make the companion-type public always.</div>
        <div>2. When introducing value-classes, document the risks of
          having "uninitialized" values under very specific
          circumstances (uninitialized fields, flat arrays).<br>
        </div>
        <div>3. Let the compiler treat fields of companion-types like
          final fields today, i.e. enforce initialization. <br>
        </div>
        <div>4. The risk of still encountering uninitialized fields is
          really really low, and is, btw, absolutely not new.<br>
        </div>
        <div>4. Provide the users with a convenient API for creating
          arrays with all elements initialized to a specific value.</div>
        <div>5. In Java, one could possibly also use this currently
          disallowed syntax for creating initialized arrays: new
          Sample.val[20] { Sample.of("Hello") };<br>
        </div>
        <div><br>
        </div>
      </div>
    </div>
  </div>

</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div></div>