<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hit send too fast...</p>
    <p>Yes, orElse alone can't set/compute the uninitialized value. So
      that's a problem (as you observed)<br>
    </p>
    <p>But orElse can't also be explained in terms of get() -- unless
      you accept doing a double access of the underlying storage.</p>
    <p>Uplevelling, I believe the fact that, in the current form,
      neither API sits cleanly on top of the other is probably a part of
      the problem highlighted in this discussion.</p>
    <p>Maurizio<br>
    </p>
    <div class="moz-cite-prefix">On 09/12/2025 11:22, Maurizio
      Cimadamore wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:37152b24-6f4c-4fb9-a2f8-c444d3be58e6@oracle.com">
      
      <p><br>
      </p>
      <div class="moz-cite-prefix">On 09/12/2025 11:15, Anatoly
        Kupriyanov wrote:<br>
      </div>
      <blockquote type="cite" cite="mid:CAGwStpBdf5Wt_Yw7_t1=rDxUMfiAj=zPn4ba4BAL22H9C4gVNA@mail.gmail.com">
        <div dir="auto">
          <div>That's seems exactly opposite. The `get` returns initial
            value always making the constant initialised by calling
            compute.</div>
          <div dir="auto">The `orElse(v)` is a shortcut for
            `c.isInitialized() ? c.get() : v`.</div>
        </div>
      </blockquote>
      <p>Not really :-)</p>
      <p>c.isInitialized also calls `getAcquire` internally (so your
        snippet would end up calling getAcquire twice in some  paths,
        once for isInitialized, and another for get).<br>
      </p>
      <p>Technically, get() can be explained as:</p>
      <p>V value = lazyConstant.orElse(sentinel)<br>
        if (value == sentinel) throw new NoSuchElementException<br>
      </p>
      <p>That performs only one call to getAcquire, not two.</p>
      <p>(We don't implement it exactly this way, but we could).</p>
      <p>Maurizio<br>
      </p>
      <blockquote type="cite" cite="mid:CAGwStpBdf5Wt_Yw7_t1=rDxUMfiAj=zPn4ba4BAL22H9C4gVNA@mail.gmail.com">
        <div dir="auto">
          <div><br>
          </div>
          <div data-smartmail="gmail_signature">WBR, Anatoly.</div>
        </div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Tue, 9 Dec 2025, 10:25
            Maurizio Cimadamore, <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" rel="noreferrer" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div>
              <p>I agree with most of the conclusions in this thread.</p>
              <p><br>
              </p>
              <p>One small nit is that, in reality, `orElse` is a
                "primitive" in disguise. E.g. you can implement `get` in
                terms of `orElse` but not the other way around (unless
                you are willing to do _two_ accessed to the underlying
                value). So, while we could drop it, we would also lose
                something (which is why we decided to keep it, at least
                for now).</p>
              <p><br>
              </p>
              <p>Maurizio<br>
              </p>
              <p><br>
              </p>
              <p><br>
              </p>
              <div>On 08/12/2025 12:31, Per-Ake Minborg wrote:<br>
              </div>
              <blockquote type="cite">
                <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
                  So, it is nice that folks seem to agree that <code>LazyConstant</code> should
                  only compute and initialize its contents from the
                  Supplier/lambda given at declaration time. The <code>orElse</code> method
                  seems to blur the contours of <code>LazyConstant</code> ,
                  and so, as previously said, we might consider removing
                  the method altogether in the next preview. <br>
                  <br>
                  It is also a fact that many have identified a need for
                  "something else more low-level" that supports a more
                  imperative programming model when working with
                  constants that are lazily set. We do not rule out that
                  such a thing might appear in a future JDK version.<br>
                  <br>
                  Best, Per</div>
                <div><br>
                  <div style="font-family:Calibri;text-align:left;color:rgb(0,0,0);margin-left:5pt;font-size:10pt">
                    Confidential- Oracle Internal</div>
                </div>
                <hr style="display:inline-block;width:98%">
                <div id="m_2056141226387924638m_-7781291897711540359divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> David Alayachew <a href="mailto:davidalayachew@gmail.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><davidalayachew@gmail.com></a><br>
                    <b>Sent:</b> Friday, December 5, 2025 2:51 PM<br>
                    <b>To:</b> Red IO <a href="mailto:redio.development@gmail.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><redio.development@gmail.com></a><br>
                    <b>Cc:</b> david Grajales <a href="mailto:david.1993grajales@gmail.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><david.1993grajales@gmail.com></a>;
                    Per-Ake Minborg <a href="mailto:per-ake.minborg@oracle.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><per-ake.minborg@oracle.com></a>;
                    amber-dev <a href="mailto:amber-dev@openjdk.org" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><amber-dev@openjdk.org></a>;
                    core-libs-dev <a href="mailto:core-libs-dev@openjdk.org" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true"><core-libs-dev@openjdk.org></a><br>
                    <b>Subject:</b> [External] : Re: Feedback about
                    LazyConstants API (JEP526)</font>
                  <div> </div>
                </div>
                <div>
                  <div dir="auto">
                    <div dir="auto">Caveat -- I have only used the Java
                      25 version of this library.</div>
                    <div dir="auto"><br>
                    </div>
                    I agree that the name orElse() is not intuitive. It
                    was made more intuitive by the existence of
                    orElseSet(). In its absence, changing the name makes
                    sense.
                    <div dir="auto"><br>
                    </div>
                    <div dir="auto">Though, I'm definitely open to just
                      removing the method. This is easy enough to
                      accomplish ourselves. Would prefer a rename
                      though.</div>
                  </div>
                  <br>
                  <div>
                    <div dir="ltr">On Fri, Dec 5, 2025, 8:32 AM Red IO
                      <<a href="mailto:redio.development@gmail.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">redio.development@gmail.com</a>>
                      wrote:<br>
                    </div>
                    <blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div dir="auto">Hi David,
                        <div dir="auto">As par already said the orElse
                          method doesn't initializes the LazyConstant. </div>
                        <div dir="auto">It just checks rather the value
                          is init and if not calls the supplier to get a
                          substitute for the missing constant. </div>
                        <div dir="auto">Example:</div>
                        <div dir="auto">LazyConstant<String> x =
                          LazyConstant.of(() -> "Const");</div>
                        <div dir="auto">var uninit1 = x.orElse(() ->
                          "substitute 1");</div>
                        <div dir="auto">var uninit2 = x.orElse(() ->
                          "substitute 2");</div>
                        <div dir="auto">var init1 = x.get();</div>
                        <div dir="auto">var init2 = x.orElse(() ->
                          "substitute 3");</div>
                        <div dir="auto">uninit1 and uninit2 get the
                          substitute 1/2</div>
                        <div dir="auto">And init1 and init2 get Const. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">This is surprising if you expect
                          it to be a way to init it with an alternative
                          value. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">My suggestion would to make the
                          separation clear and allow for another use
                          case by spliting this api in 2 parts:</div>
                        <div dir="auto">One class LazyConstant </div>
                        <div dir="auto">Takes a Supplier in static
                          factory and exposes get() </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">And</div>
                        <div dir="auto">Class LazyInit</div>
                        <div dir="auto">Which takes no arguments in the
                          static factory and takes a supplier in the get
                          method that gets called when get is called for
                          the first time. </div>
                        <div dir="auto">In this case the source for the
                          constant can be any piece of code that has
                          access to the LazyConstant. This might be
                          desired in some cases. In cases where it's not
                          the other version can be used. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">This split makes it clear from
                          which context the constant is initialized from
                          (consumer or at declaration) </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">Mixing those 2 or having methods
                          that appear to do this is rather confusing. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">One solution for the "i might
                          not want to init the constant" case the
                          "orElse" method is meant to be is to have a
                          method "tryGet" which returns Optional
                          instead. This makes it clear that the value
                          might not be there and is not initialized when
                          calling the method. Nobody expects to init the
                          constant when calling orElse on a returned
                          Optional. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">My 2 suggestions here are
                          completely independent and should be viewed as
                          such. </div>
                        <div dir="auto"><br>
                        </div>
                        <div dir="auto">Great regards </div>
                        <div dir="auto">RedIODev </div>
                      </div>
                      <br>
                      <div>
                        <div dir="ltr">On Fri, Dec 5, 2025, 13:55 david
                          Grajales <<a href="mailto:david.1993grajales@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">david.1993grajales@gmail.com</a>>
                          wrote:<br>
                        </div>
                        <blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                          <div dir="ltr">HI Per. I pleasure to talk with
                            you.
                            <div><br>
                            </div>
                            <div>You are right about one thing but this
                              actually makes the API less intuitive and
                              harder to read and reason about.</div>
                            <div><br>
                            </div>
                            <div>LazyConstant<String> foo =
                              LazyConstant.of(() -> "hello");<br>
                              <br>
                              void main() {<br>
                                  if (someCondition()) {// asume false<br>
                                      foo.get();<br>
                                  }<br>
                                  foo.orElse("hello2"); // ...<br>
                              <br>
                                  println(foo.get()); // This prints
                              "hello"<br>
                              }</div>
                            <div><br>
                            </div>
                            <div>But if one assigns foo.orElse("hello2")
                              to a variable, the variable actually gets
                              the "hello2" value.</div>
                            <div><br>
                            </div>
                            <div>void main() {<br>
                                  if (someCondition()) {// asume false<br>
                                      foo.get();<br>
                                  }<br>
                                  var res = foo.orElse("hello2"); // ...</div>
                            <div>    var res2 = foo.orElse("hello3");<br>
                                  println(res); // This prints "hello2"</div>
                            <div>    println(res2);//This prints
                              "hello3"<br>
                              }<br>
                            </div>
                            <div><br>
                            </div>
                            <div>This is actually even more confusing
                              and makes the API more error prone. I
                              personally think once initialized the lazy
                              constant should always return the same
                              value (maybe through the .get() method
                              only), and there should not be any
                              possibility of getting a different
                              values from the same instance either in
                              the .of() static method or in any
                              hypothetical instance method for
                              conditional downstream logic.  I guess one
                              could achieve the latter with the static
                              factory method through something like this
                              (although less elegant)</div>
                            <div><br>
                            </div>
                            <div>private class Bar{<br>
                                  private final
                              LazyConstant<String> foo;<br>
                                  private Bar(Some some){<br>
                              <br>
                                      if(some.condition){<br>
                                          foo = LazyConstant.of(() ->
                              "hello");<br>
                                      }else {<br>
                                          foo = LazyConstant.of(() ->
                              "hello2");<br>
                                      }<br>
                                  }<br>
                              }</div>
                            <div><br>
                            </div>
                            <div>Thank you for reading. This is all I
                              have to report. </div>
                            <div><br>
                            </div>
                            <div>Best regards.</div>
                            <div><br>
                            </div>
                            <div><br>
                            </div>
                          </div>
                          <br>
                          <div>
                            <div dir="ltr">El vie, 5 dic 2025 a la(s)
                              6:05 a.m., Per-Ake Minborg (<a href="mailto:per-ake.minborg@oracle.com" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">per-ake.minborg@oracle.com</a>)
                              escribió:<br>
                            </div>
                            <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                              <div>
                                <div dir="ltr">
                                  <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
                                    Hi David,<br>
                                    <br>
                                    Thank you for trying out
                                    LazyConstant and providing feedback.
                                    That is precisely what previews are
                                    for!<br>
                                    <br>
                                  </div>
                                  <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
                                    If you take a closer look at the
                                    specification of <code>LazyConstant::orElse,</code> it
                                    says that the method will <i>never
                                      trigger initialization.</i> And
                                    so, you <i>can</i> actually be sure
                                    that in your first example, <code>foo</code> is
                                    always initialized to "hello" (if
                                    ever initialized). It is only if foo
                                    is not initialized that the method
                                    will return "hello2" (again, without
                                    initializing foo). This is similar
                                    to how <code>Optional</code> works.<br>
                                    <br>
                                    It would be possible to entirely
                                    remove the <code>orElse()</code> method
                                    from the API, and in the rare cases
                                    where an equivalent functionality is
                                    called for, rely on <code>LazyConstant::isInitialized</code> instead.<br>
                                    <br>
                                    Best, Per</div>
                                  <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
                                    <br>
                                  </div>
                                  <div id="m_2056141226387924638m_-7781291897711540359x_m_-2042492114742708934m_-8766186915558418911m_-1330836081727153577appendonsend">
                                  </div>
                                  <div><br>
                                    <div style="font-family:Calibri;text-align:left;color:rgb(0,0,0);margin-left:5pt;font-size:10pt">
                                      Confidential- Oracle Internal</div>
                                  </div>
                                  <hr style="display:inline-block;width:98%">
                                  <div id="m_2056141226387924638m_-7781291897711540359x_m_-2042492114742708934m_-8766186915558418911m_-1330836081727153577divRplyFwdMsg" dir="ltr"> <font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b>
                                      amber-dev <<a href="mailto:amber-dev-retn@openjdk.org" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amber-dev-retn@openjdk.org</a>>
                                      on behalf of david Grajales <<a href="mailto:david.1993grajales@gmail.com" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">david.1993grajales@gmail.com</a>><br>
                                      <b>Sent:</b> Friday, December 5,
                                      2025 5:38 AM<br>
                                      <b>To:</b> amber-dev <<a href="mailto:amber-dev@openjdk.org" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amber-dev@openjdk.org</a>>;
                                      <a href="mailto:core-libs-dev@openjdk.org" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">
                                        core-libs-dev@openjdk.org</a>
                                      <<a href="mailto:core-libs-dev@openjdk.org" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">core-libs-dev@openjdk.org</a>><br>
                                      <b>Subject:</b> Feedback about
                                      LazyConstants API (JEP526)</font>
                                    <div> </div>
                                  </div>
                                  <div>
                                    <div dir="ltr">Dear Java Dev Team, 
                                      <div><br>
                                      </div>
                                      <div> I am writing to provide
                                        feedback and two specific
                                        observations regarding the
                                        LazyConstant API, which is
                                        currently a preview feature in
                                        OpenJDK 26. </div>
                                      <div><br>
                                      </div>
                                      <div> I appreciate the API's
                                        direction and I think it's a
                                        good improvement compared to its
                                        first iteration; however, I see
                                        potential for improved
                                        expressiveness, particularly in
                                        conditional scenarios.</div>
                                      <div><br>
                                      </div>
                                      <div><br>
                                      </div>
                                      <div><b>1. Proposal:
                                          Zero-Parameter
                                          `LazyConstant.of()` Overload:</b> 
                                         </div>
                                      <div><br>
                                      </div>
                                      <div>Currently, the mandatory use
                                        of a factory method receiving a
                                        `Supplier` (due to the lack of a
                                        public constructor) can obscure
                                        the expressiveness of
                                        conditional or multiple-value
                                        initialization paths. **The
                                        Issue:** When looking at the
                                        declaration:</div>
                                      <div><br>
                                      </div>
                                      <div>LazyConstant<String>
                                        foo = LazyConstant.of(() ->
                                        "hello");</div>
                                      <div><br>
                                      </div>
                                      <div>the code gives the strong,
                                        immediate impression that the
                                        value is <b>always</b>
                                        initialized to <code>"hello"</code>.
                                        This makes it difficult to infer
                                        that the constant might
                                        ultimately resolve to an
                                        alternative value set later via
                                        <code>orElse()</code> or another
                                        conditional path, especially
                                        when skimming the code:</div>
                                      <div><br>
                                      </div>
                                      <div>LazyConstant<String>
                                        foo = LazyConstant.of(() -> <span>"hello"</span>);
                                        // When skimming the code it's
                                        not always obvious that this may
                                        not be the actual value </div>
                                      <div>  </div>
                                      <div><span><span>void</span> <span>main</span><span>()</span>
                                        </span>{ </div>
                                      <div>  <span>if</span>
                                        (someCondition()) { </div>
                                      <div>          foo.get(); <span>//
                                          Trigger initialization to
                                          "hello"</span> </div>
                                      <div> } </div>
                                      <div>  <span>// If someCondition
                                          is false, the final value of
                                          foo is determined here:</span> </div>
                                      <div>  <span>var</span> res1 =
                                        foo.orElse(<span>"hello2"</span>);
                                        <span>// ...</span> </div>
                                      <div>}</div>
                                      <div><br>
                                      </div>
                                      <div><b>My Suggestion:</b> I
                                        propose introducing a <b>zero-parameter
                                          overloaded static factory
                                          method</b> <code>of()</code>:</div>
                                      <div><br>
                                      </div>
                                      <div>LazyConstant<String>
                                        foo = LazyConstant.of();</div>
                                      <div><br>
                                      </div>
                                      <div>This form explicitly
                                        communicates that the constant
                                        is initialized to an <b>
                                          unresolved</b> state,
                                        suggesting that the value will
                                        be determined downstream by the
                                        first invocation of an
                                        initialization/computation
                                        method.</div>
                                      <div><br>
                                      </div>
                                      <div>LazyConstant<String>
                                        foo = LazyConstant.of(); <span>//
                                          Clearly unresolved</span> </div>
                                      <div>  <span><span>void</span> <span>main</span><span>()</span>
                                        </span>{ </div>
                                      <div>  <span>if</span>
                                        (someCondition()) { </div>
                                      <div>      foo.orElse(<span>"hello"</span>); </div>
                                      <div> } </div>
                                      <div>  <span>var</span> res1 =
                                        foo.orElse(<span>"hello2"</span>);
                                        <span>// ...</span> </div>
                                      <div>}</div>
                                      <div><br>
                                      </div>
                                      <div>This is specially useful for
                                        clarity when one has conditional
                                        initialization in places such as
                                        the constructor of a class. For
                                        example</div>
                                      <div><br>
                                      </div>
                                      <div>
                                        <p>private class Bar{<br>
                                              LazyConstant<String>
                                          foo = LazyConstant.of();<br>
                                              private Bar(Some some){<br>
                                                  if(some.condition()){<br>
                                                      foo.orElse("foo");<br>
                                                  }<br>
                                                  foo.orElse("foo2");<br>
                                              }<br>
                                          <br>
                                              String computeValue() {<br>
                                                  return "hello";<br>
                                              }<br>
                                          <br>
                                              String computeValue2(){<br>
                                                  return "hello2";<br>
                                              }<br>
                                          }</p>
                                      </div>
                                      <div>
                                        <h3>2. Method Naming Suggestion
                                          and and supplier in instance
                                          method for consistency in the
                                          API</h3>
                                        <p>My second, much more minor
                                          observation relates to the
                                          instance method <code>orElse(T
                                            t)</code>.</p>
                                        <p>While <code>orElse</code>
                                          fits a retrieval pattern, I
                                          personally feel that <b> <code>compute</code></b>
                                          or <b><code>computeIfAbsent</code></b>
                                          would better express the
                                          intent of this method, as its
                                          primary function is not just
                                          to retrieve, but to trigger
                                          the computation and <b>set
                                            the final value</b> of the
                                          constant if it is currently
                                          uninitialized. Also, as the
                                          factory of() has a supplier i
                                          think this instance method
                                          should also receive a
                                          Supplier, This not only keeps
                                          the API consistent in the
                                          usage but makes more ergonomic
                                          the declaration of complex
                                          initialization logic inside
                                          the method.</p>
                                        <p><br>
                                        </p>
                                        <p>private class Bar{<br>
                                             
                                          LazyConstant<InitParams>
                                          foo =
                                          LazyConstant.of(InitParam::default);
                                          // Under the current API this
                                          is mandatory but in reality
                                          the value is set in the
                                          constructor, default is never
                                          really used.<br>
                                              private Bar(Some some){<br>
                                               
                                           foo.compute(some::executeCallToCacheDBAndBringInitializationParams)
                                          //Real configuration happens
                                          here</p>
                                        <p>    }<br>
                                          }</p>
                                        <p>This last it's very common
                                          for initialization of
                                          configuration classes and
                                          singletons.</p>
                                        <p><br>
                                        </p>
                                        <p>Thank you so much for your
                                          attention, I hope you find
                                          this feedback useful.</p>
                                        <p>Always yours. David Grajales</p>
                                      </div>
                                    </div>
                                  </div>
                                </div>
                              </div>
                            </blockquote>
                          </div>
                        </blockquote>
                      </div>
                    </blockquote>
                  </div>
                </div>
              </blockquote>
            </div>
          </blockquote>
        </div>
      </blockquote>
    </blockquote>
  </body>
</html>