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