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 <[email protected]> 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 <[email protected]> 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 >
