<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <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 class="moz-cite-prefix">On 08/12/2025 12:31, Per-Ake Minborg
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:SA1PR10MB7832EF3118799DE345DCBD74DAA2A@SA1PR10MB7832.namprd10.prod.outlook.com">
      
      <style type="text/css" style="display:none;">P {margin-top:0;margin-bottom:0;}</style>
      <div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
        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%" tabindex="-1">
      <div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> David
          Alayachew <a class="moz-txt-link-rfc2396E" href="mailto:davidalayachew@gmail.com"><davidalayachew@gmail.com></a><br>
          <b>Sent:</b> Friday, December 5, 2025 2:51 PM<br>
          <b>To:</b> Red IO <a class="moz-txt-link-rfc2396E" href="mailto:redio.development@gmail.com"><redio.development@gmail.com></a><br>
          <b>Cc:</b> david Grajales
          <a class="moz-txt-link-rfc2396E" href="mailto:david.1993grajales@gmail.com"><david.1993grajales@gmail.com></a>; Per-Ake Minborg
          <a class="moz-txt-link-rfc2396E" href="mailto:per-ake.minborg@oracle.com"><per-ake.minborg@oracle.com></a>; amber-dev
          <a class="moz-txt-link-rfc2396E" href="mailto:amber-dev@openjdk.org"><amber-dev@openjdk.org></a>; core-libs-dev
          <a class="moz-txt-link-rfc2396E" href="mailto:core-libs-dev@openjdk.org"><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 class="x_gmail_quote x_gmail_quote_container">
          <div dir="ltr" class="x_gmail_attr">On Fri, Dec 5, 2025,
            8:32 AM Red IO <<a href="mailto:redio.development@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">redio.development@gmail.com</a>>
            wrote:<br>
          </div>
          <blockquote class="x_gmail_quote" 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 class="x_gmail_quote">
              <div dir="ltr" class="x_gmail_attr">On Fri, Dec 5, 2025,
                13:55 david Grajales <<a href="mailto:david.1993grajales@gmail.com" target="_blank" rel="noreferrer" moz-do-not-send="true" class="moz-txt-link-freetext">david.1993grajales@gmail.com</a>>
                wrote:<br>
              </div>
              <blockquote class="x_gmail_quote" 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 class="x_gmail_quote">
                  <div dir="ltr" class="x_gmail_attr">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" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">per-ake.minborg@oracle.com</a>)
                    escribió:<br>
                  </div>
                  <blockquote class="x_gmail_quote" 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="x_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="x_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" 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" 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" 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" 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" 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>
  </body>
</html>