<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
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);" class="elementToProof">
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);" class="elementToProof">
<br>
</div>
<div id="appendonsend"></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 face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> amber-dev <amber-dev-retn@openjdk.org> on behalf of david Grajales <david.1993grajales@gmail.com><br>
<b>Sent:</b> Friday, December 5, 2025 5:38 AM<br>
<b>To:</b> amber-dev <amber-dev@openjdk.org>; core-libs-dev@openjdk.org <core-libs-dev@openjdk.org><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 class="x_gmail-hljs-string">
"hello"</span>); // When skimming the code it's not always obvious that this may not be the actual value </div>
<div>  </div>
<div><span class="x_gmail-hljs-function"><span class="x_gmail-hljs-keyword">void</span>
<span class="x_gmail-hljs-title">main</span><span class="x_gmail-hljs-params">()</span>
</span>{ </div>
<div>  <span class="x_gmail-hljs-keyword">if</span> (someCondition()) { </div>
<div>          foo.get(); <span class="x_gmail-hljs-comment">// Trigger initialization to "hello"</span> </div>
<div> } </div>
<div>  <span class="x_gmail-hljs-comment">// If someCondition is false, the final value of foo is determined here:</span> </div>
<div>  <span class="x_gmail-hljs-keyword">var</span> res1 = foo.orElse(<span class="x_gmail-hljs-string">"hello2"</span>);
<span class="x_gmail-hljs-comment">// ...</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 class="x_gmail-hljs-comment">
// Clearly unresolved</span> </div>
<div>  <span class="x_gmail-hljs-function"><span class="x_gmail-hljs-keyword">void</span>
<span class="x_gmail-hljs-title">main</span><span class="x_gmail-hljs-params">()</span>
</span>{ </div>
<div>  <span class="x_gmail-hljs-keyword">if</span> (someCondition()) { </div>
<div>      foo.orElse(<span class="x_gmail-hljs-string">"hello"</span>); </div>
<div> } </div>
<div>  <span class="x_gmail-hljs-keyword">var</span> res1 = foo.orElse(<span class="x_gmail-hljs-string">"hello2"</span>);
<span class="x_gmail-hljs-comment">// ...</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></p>
<p></p>
<p></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>
</body>
</html>