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