<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<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">
Hello David, and thank you for getting back to us with feedback on the Lazy Constants API.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
In the second preview, LazyConstant can not be set imperatively. In other words, we have removed the old
<code>StableValue</code> methods: <code>trySet()</code>, <code>setOrThrow()</code> and
<code>orElseSet()</code> as they were generally difficult to use and were prone to creating boxing, lambda capturing, and locking issues, which could negatively impact both performance, code readability, and application maintenance costs.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Instead, an underlying computing function must now be given at construction time. The various use cases we have identified indicate that this simplification of the API still covers a vast majority of those cases. However, there are other, more complicated cases
 that are not easily supported by <code>LazyConstant</code> and for which a more lower-level access capability would be appropriate.  We are planning to address this in future works, separate from
<code>LazyConstant</code>. We will add that piece of information to the JEP, so thank you for identifying this. With respect to adding separate language constructs, such as a lazy keyword, the bar for this is extremely high and would have to be motivated and
 gauged against other potential language improvements, such as evolving pattern matching.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Note that <code>LazyConstant</code> now has a <code>get()</code> method, and that it also implements
<code>Supplier</code> for easy integration with existing code.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Here is what your first example could look like with the new API:<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">
<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">
        private static final LazyConstant<MySingleton> MESSAGE =</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
                LazyConstant.of(() -> new MySingleton("Hello Java"));</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
        void main(){</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
            IO.println(MESSAGE.get().message());</div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
        }</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
        private record MySingleton(String message){ }<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">
<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">
This will provide constant folding of the `MESSAGE.get().message()` sequence in case the JIT compiler decides to compile it.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
I think the other examples you show (albeit I didn't fully get how they were supposed to work) would have issues regardless of whether there were language or library support for lazy computation, because the initialization logic is not known at declaration
 time. Some other languages (like Kotlin's `lateinit` [1]) have constructs that would seem to fit at a first glance, but they come with other severe semantic limitations (such as lack of thread-safety, lack of support for primitive types, and no constant folding).
 We want to do better and will, as previously said, address this down the road.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Thanks again for your feedback, David.</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 style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);" class="elementToProof">
Best, Per Minborg<br>
<br>
[1] <a id="LPlnk957058" href="https://medium.com/@anandgaur2207/lateinit-vs-lazy-in-kotlin-9608fb286fc6">
https://medium.com/@anandgaur2207/lateinit-vs-lazy-in-kotlin-9608fb286fc6</a></div>
<div style="width: 100%; display: inline-block;" class="_Entity _EType_OWALinkPreview _EId_OWALinkPreview _EReadonly_1">
<div style="width: 100%; margin-top: 16px; margin-bottom: 16px; position: relative; max-width: 800px; min-width: 424px;" class="LPBorder854696" id="LPBorder_GTaHR0cHM6Ly9tZWRpdW0uY29tL0BhbmFuZGdhdXIyMjA3L2xhdGVpbml0LXZzLWxhenktaW4ta290bGluLTk2MDhmYjI4NmZjNg..">
<table style="padding: 12px 36px 12px 12px; width: 100%; border-width: 1px; border-style: solid; border-color: rgb(200, 200, 200); border-radius: 2px;" role="presentation" id="LPContainer854696">
<tbody>
<tr style="border-spacing: 0px;" valign="top">
<td>
<div style="position: relative; margin-right: 12px; height: 120px; overflow: hidden; width: 240px;" id="LPImageContainer854696">
<a href="https://medium.com/@anandgaur2207/lateinit-vs-lazy-in-kotlin-9608fb286fc6" id="LPImageAnchor854696" target="_blank"><img width="240" style="display: block;" height="120" alt="" id="LPThumbnailImageId854696" src="https://miro.medium.com/v2/resize:fit:1200/0*BqZDTJExg-RoB9qm.png"></a></div>
</td>
<td style="width: 100%;">
<div style="font-size: 21px; font-weight: 300; margin-right: 8px; font-family: wf_segoe-ui_light, "Segoe UI Light", "Segoe WP Light", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; margin-bottom: 12px;" id="LPTitle854696">
<a style="text-decoration: none; color: var(--themePrimary);" href="https://medium.com/@anandgaur2207/lateinit-vs-lazy-in-kotlin-9608fb286fc6" id="LPUrlAnchor854696" target="_blank">Lateinit vs Lazy in Kotlin - Medium</a></div>
<div style="font-size: 14px; max-height: 100px; color: rgb(102, 102, 102); font-family: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; margin-bottom: 12px; margin-right: 8px; overflow: hidden;" id="LPDescription854696">
Lateinit vs Lazy in Kotlin When building Android apps in Kotlin, you often need to initialize variables, but the exact moment of initialization may vary depending on your app’s requirements ...</div>
<div style="font-size: 14px; font-weight: 400; color: rgb(166, 166, 166); font-family: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif;" id="LPMetadata854696">
medium.com</div>
</td>
</tr>
</tbody>
</table>
</div>
</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="appendonsend"></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> Wednesday, September 24, 2025 4:02 AM<br>
<b>To:</b> amber-dev <amber-dev@openjdk.org><br>
<b>Subject:</b> Feedback on LazyConstants (formerly StableValues)</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<p>Dear Amber team,</p>
<p>I hope this message finds you well. First of all, I want to extend my gratitude for all your hard work in continuously improving the Java platform — it is very much appreciated.</p>
<p>I have been experimenting with the <code>StableValues</code> API (now renamed <code>
LazyConstants</code>) and attempting to use it in place of some of my older automation scripts for personal projects. While doing so, I noticed that the current design feels a bit rigid in certain scenarios, and this may indicate that a keyword or annotation-based
 solution could be a better fit.</p>
<p>Let me illustrate with a simple example. A common case of deferred initialization is the lazy singleton pattern:</p>
<div><br>
</div>
<div>void main(){<br>
    var message = MySingleton.getInstance("Hello java").getMessage();<br>
    println(message);<br>
}<br>
<br>
private static class MySingleton{<br>
    private static MySingleton instance;<br>
    private final String message;<br>
<br>
    private MySingleton(String message) {<br>
        this.message = message;<br>
    }<br>
<br>
    public static  MySingleton getInstance(String message) {<br>
        if (instance == null) {<br>
            instance = new MySingleton(message);<br>
        }<br>
        return instance;<br>
    }<br>
    public String getMessage() {<br>
        return message;<br>
    }<br>
}</div>
<div><br>
</div>
<div>
<p>While this works, the result feels neither more concise nor more readable. The code is now cluttered by the API’s requirements rather than improved by them.</p>
<p><br>
</p>
</div>
<div><br>
</div>
<div>public class MySingleton2 {<br>
    private static final StableValue<MySingleton2> instance = StableValue.of();<br>
    private final String message;<br>
<br>
    private MySingleton2(String message) {<br>
        this.message = message;<br>
    }<br>
<br>
    public static MySingleton2 getInstance(String message){<br>
        return instance.orElse(new MySingleton2(message));<br>
    }<br>
<br>
    public String getMessage(){<br>
        return message;<br>
    }<br>
}<br>
</div>
<div><br>
</div>
<div>The issue here is that the current API does not offer a way to lazily capture constructor parameters — for example, through a <code>Function</code> or <code>Supplier</code>-based variant. Something like this would feel more natural:</div>
<div><br>
</div>
<div>public  <T, R>StableValue<R> createLazy(T t, Function<T, R> underlying){<br>
    return StableValue.of(underlying.apply(t));<br>
}</div>
<div><br>
</div>
<div>final StableValue<MySingleton> instanceLazy = createLazy("Hello", MySingleton::getInstance);</div>
<div><br>
</div>
<div>Now let's take a look to the case where the message field is lazy too.</div>
<div><br>
</div>
<div>public class MySingleton3 {<br>
    private static final LazyConstant<MySingleton3> instance =<br>
            LazyConstant.of(ew MySingleton3());<br>
<br>
    private LazyConstant<String> message;<br>
<br>
    private MySingleton3() {<br>
        // constructor doesn't accept the dynamic value in this pattern,<br>
        // so the message must be initialized separately.<br>
    }<br>
<br>
 <br>
    public static MySingleton3 getInstance(String value) {<br>
        // obtain the singleton (or create one if absent)<br>
        MySingleton3 s = instance.orElse(new MySingleton3());<br>
<br>
        // awkward: we must initialise the instance's lazy message here to capture `value`<br>
        if (s.message == null) {<br>
            s.message = LazyConstant.of(s.computeMessage(value));<br>
        }<br>
<br>
        return s;<br>
    }<br>
<br>
    public String getMessage() {<br>
        // we assume getInstance(...) has already set `message`; read it with orElse(null)<br>
        // (using `null` here to avoid any extra computation as orElse takes a concrete value).<br>
        return message.orElse(null);<br>
    }<br>
<br>
    private String computeMessage(String value) {<br>
        return "Hello " + value;<br>
    }<br>
<br>
    public static void main(String[] args) {<br>
        // prints "Computing message..." once, then "Hello Java"<br>
       println(MySingleton3.getInstance("Java").getMessage());<br>
        <br>
    }<br>
}</div>
<div><br>
</div>
<div>As you can see, there is no real improvement from a code perspective — in fact, the resulting implementation is
<em>harder to reason about</em>. The mental model for the developer becomes more complex, since they must explicitly manage when and how values are captured. Additionally, the lack of a simple
<code>get()</code> method (having only <code>orElse(...)</code> and <code>orElseThrow(...)</code>) makes the code more verbose and slightly redundant, especially in cases where you know the value has already been initialized.</div>
<div><br>
</div>
<div>Now, the issue is not the lack of this or other methods. The issue relies on the infinite possible combinations that makes the design of a simple but flexible enough API a hard to achieve task. Seeing this limitation and the past limitations I have already
 shared in this mailing list, i am not sure if an API based approach is the best solution. I understand the good thing about API based features are how easy they are to grow, at least compared to a language level feature, but the current approach i fear may
 lead to an ever expanding API that would never be enough.</div>
<div><br>
</div>
<div>
<p>Considering this, and similar concerns I have previously shared here, I wonder if an API-based approach is really the right long-term solution. While API-based features are easier to evolve than language features, I worry that this approach could lead to
 an ever-expanding API that still never quite covers all the practical cases developers face. My current impression is that the API gets in the way more than it helps. Java already provides more natural ways to achieve lazy initialization, and
<code>LazyConstants</code> ends up feeling like a low-level optimization, ceremony aimed at squeezing out marginal performance gains that may not even justify the added complexity.</p>
<p>I would love to hear your thoughts, pointing me to a better direction about how to use the API for this kind of cases. Is there something that i am not seeing?</p>
<p>Thank you for your time and for continuing to improve the Java platform.</p>
<p>Best regards and always yours: David Grajales Cardenas.</p>
</div>
<div><br>
</div>
</div>
</div>
</body>
</html>