[External] : Re: Feedback about LazyConstants API (JEP526)

david Grajales david.1993grajales at gmail.com
Tue Dec 9 14:46:39 UTC 2025


I am glad my feedback was helpful and sparkled such a great discussion. I
would like to put 2 cents more, looking for these to be helpful.

My main concern with "orElse" is that most of the time (at least for my how
I would use this API in my job) most of the time I need a reliable way to
set the constant and use that particular constant along the life cycle of
the class, **not** declaring an alternative local variable in replacement
because most of the time there is no good "burned in the code"
alternatives  that I could use . The use cases I have for this API are
usually about deferred initialization of values that often require some
time costly operation, some of those may involve calls to external services
(IO operations) thus having a "burned" constant in these cases is not
useful. Instead I propose a "computeIfAbsent" (I am not against orElse
naming) method that allows for alternative downstream conditional
initialization of the Lazy constant.


private class Bar{
    LazyCosntan<Weather> weatherUrl =
LazyCosntant.of(this::checkAndGetWeatherUrl);


    public Bar(){}

    private String checkAndGetWeatherUrl(){
        return Executors.newVirtualThreadPerTaskExecutor()
            .submit(() -> /*Some query to check if the weather server is up*/);
    }

    private String checkAndGetAltWeatherUrl(){
        return Executors.newVirtualThreadPerTaskExecutor()
            .submit(() -> /*Some query to check if the alt weather
server is up*/);
    }

    public Weather getWeather(){

        var url =
weatherUrl.computeIfAbsent(this::checkAndGetAltWeatherUrl).get();

        // logic to get the weather here using the lazy constants//
    }

    public void sendWeather(){

    var url = weatherUrl.computeIfAbsent(this::checkAndGetAltWeatherUrl).get();

    Executors.newVirtualThreadPerTaskExecutor()
        .submit(() -> /*Send the weather url to somewhere else* using
weatherUrl*/);
    }


}


This pattern is very common, either for a trivial weather or to check or a
conf and alternatives in case the regular one is not available (for example
a conf file that may be missing and one may set a method that downloads it
from a remote server first in case it is absent)

So for me the issue is not the concept of "orElse" but how the current
implementation returns me an alternative value instead of SETTING an
alternative value in case the regular attempt fails or hasn't been called
still because the program followed an alternative path before the obvious
regular initialization path. If the orElse (or any other name that fits)
changes the behaviour to set a value instead of returning something it
would be the best approach IMHO.




El mar, 9 dic 2025 a la(s) 9:13 a.m., Anatoly Kupriyanov (kan.izh at gmail.com)
escribió:

> My idea is not an optional *interface*, but an interface for something
> which is convertible to the Optional *type*. In other words, neither the
> LazyConstant nor to ScopedVariable *is not* an optional itself, but could
> be converted to it uniformly.
> Something like this:
>
> interface Optionable<T> {// need to think about the better naming!
>   T orElse(T other);
>
>    // and maybe even:
>    default Optional<T> asOptional() {
>     return Optional.ofNullable(this.orElse(null));
>    };
> }
>
> and then LazyConstant, ScopedVariable, etc could just implement the
> interface to unify on the notion of "return a user-provided value
> if some condition isn't met". Sounds like a decent path to abolish nulls.
>
> But I feel I am overthinking this...
>
>
> On Tue, 9 Dec 2025 at 13:35, Red IO <redio.development at gmail.com> wrote:
>
>> I initially thought I agree with your statement that orElse is a common
>> pattern in the jdk. But then I failed to come up with a second example. I
>> then searched the jdk github repo for the method. And I only found Optional
>> and it's specializations and ClassHierarchyResolver.
>> So I would suggest yes, it's an often used method ... of the Optional
>> class. Not many apis seem to expose it. The case of exposing an accessor
>> that returns an Optional on the other hand is incredibly common across the
>> jdk. This is exactly the case Optional was designed for. In this sense
>> Optional is the "Interface" you are suggesting.
>>
>> My main argument against reusing orElse here is that the context is a
>> completely different one.
>> An Optional orElse method is a pure function that always returns the same
>> value. It signals that the value is not there.
>> LazyConstant is different in this regard. The LazyConstant orElse is not
>> pure at all. It depends on rather someone else already initialized the
>> value or not. It signals that the value is not there YET.
>>
>> Great regards
>> RedIODev
>>
>>
>>
>> On Tue, Dec 9, 2025, 13:51 Anatoly Kupriyanov <kan.izh at gmail.com> wrote:
>>
>>> Right, the ScopedValue is another good example I've forgotten. In that
>>> case I am even more inclined to keep the `orElse` as it looks like a
>>> repeating pattern across JDK libraries. Consistency is the way to go!
>>> And maybe even consider having a new interface for the method to make
>>> this pattern explicit?..
>>>
>>> I am glad that `orElseSet` is removed, the side-effecting is bad; also
>>> in other parts of JDK we already have `computeIfAbsent` for the same idea.
>>> I did not hear about it, and yeah, sounds like the source of this confusion.
>>>
>>>
>>> On Tue, 9 Dec 2025 at 12:05, Maurizio Cimadamore <
>>> maurizio.cimadamore at oracle.com> wrote:
>>>
>>>>
>>>> On 09/12/2025 11:59, Anatoly Kupriyanov wrote:
>>>> > To be honest, I don't really see why this method causes such
>>>> confusion.
>>>>
>>>> In part I agree. E.g. when we added this, what we had in mind was just
>>>>
>>>>
>>>> https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/ScopedValue.html#orElse(T)
>>>>
>>>> E.g. other APIs have `orElse` method that return a user-provided value
>>>> if some condition isn't met.
>>>>
>>>> I believe the problem we're discussing here is likely also related to
>>>> the fact that the API used to have a side-effecting `orElseSet`, which
>>>> is now removed, and I wonder if, because of that, folks are reading too
>>>> much into what orElse does?
>>>>
>>>> Maurizio
>>>>
>>>>
>>>
>>> --
>>> WBR, Anatoly.
>>>
>>
>
> --
> WBR, Anatoly.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20251209/08cc7b77/attachment-0001.htm>


More information about the amber-dev mailing list