Optional.orElseChain ?

Paul Sandoz paul.sandoz at oracle.com
Tue Apr 28 13:09:00 UTC 2015


Hi Remi,

Chasing this up. I have not joined the dark-side just yet... but can you log an issue for this?

Thanks,
Paul.

On Apr 20, 2015, at 4:27 PM, Remi Forax <forax at univ-mlv.fr> wrote:

> 
> On 04/20/2015 01:39 PM, Paul Sandoz wrote:
>> Hi Remi,
>> 
>> I was gonna propose the same trick you mentioned in your last email :-)
> 
> yes, it's the same as
>  optional.map(Stream::of).orElseGet(() -> Stream.empty())
> (I use orElseGet() because Stream.empty() is not a constant !).
> 
>> 
>> Similar tricks are possible for other cases like an equivalent of the recently added ifPresentOrElse, but that was considered a little obtuse.
>> 
>> 
>> On Apr 17, 2015, at 11:37 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>>> Hi guys,
>>> I was trying to write a code that uses Optional and I think one method is missing.
>>> 
>> There is always one more (or four more including the primitive variants) :-)
> 
> Yes, yet another one.
> 
> Note that technically, the only thing you need is to be able to do pattern matching on the two states,
> so if you have a way to do a flatMap() for the case with a value and a flatMap() for the case with no value,
> you're done.
> 
> Doing a flatMap for the case with no value is exactly what you have called 'or'.
> So it's yet another method to add but it's the last one :)
> 
>> 
>> We avoided supporting both the present and absent axes in the intermediate operations (e.g. additional methods with a supplier on absence).
>> 
>> This seems like a special intermediate operation, injecting an alternative optional on absence, rather than associated with the orElse terminal operations that return T:
>> 
>>   public Optional<T> or(Supplier<Optional<T>> mapper) {
>>       Objects.requireNonNull(mapper);
>>       if (isPresent()) {
>>           return this;
>>       } else {
>>           return Objects.requireNonNull(mapper.get());
>>       }
>>   }
> 
> yes,
> 
>> 
>> But it has some terminal like qualities to it. It really only makes sense once, or once after each flatMap. I am concerned that a bunch of these sprinkled within a sequence of fluent calls might make it hard to reason about.
>> 
>> As such a static method might be more appropriate, but then it's easy for someone to add one in their own code:
>> 
>> static <T> Optional<T> or(Optional<T> a, Supplier<? extends Optional<T>> b) {
>>     Objects.requireNonNull(a);
>>     Objects.requireNonNull(b);
>>     return a.isPresent() ? a : Objects.requireNonNull(b.get());
>> }
>> 
>> static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
>>     Objects.requireNonNull(a);
>>     Objects.requireNonNull(b);
>>     return a.isPresent() ? a : b;
>> }
>> 
>> Perhaps the non-obvious thing about these is a null return should not be allowed.
> 
> But mixing static methods and instance methods is not readable too,
> instance methods goes left to right and static methods goes right to left.
> 
>> 
>> I am somewhat on the fence here...
> 
> If you only knew the power of the Dark Side :)
> 
>> 
>> Paul.
> 
> Rémi
> 



More information about the core-libs-dev mailing list