Hi Remi, I was gonna propose the same trick you mentioned in your last email :-)
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 <fo...@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) :-) 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()); } } 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. I am somewhat on the fence here... Paul. > Let suppose I want to load a type (like a class, an interface, etc) that can > come > either by reflection, or by using ASM. > I will write an interface TypeProvider that is able to load a Type and > i will chain the different type providers like this: > > TypeProvider asmTypeProvider = ... > TypeProvider reflectionTypeProvider = ... > TypeProvider provider = > asmTypeProvider.chain(reflectionTypeProvider).orFail(); > > so I've implemented TypeProvider like this: > > public interface TypeProvider { > public Optional<Type> loadType(String name); > > public default TypeProvider chain(TypeProvider provider) { > return name -> { > Optional<Type> type = loadType(name); > return type.isPresent()? type: provider.loadType(name); > }; > } > > public default TypeProvider orFail() { > return chain(fail()); > } > > public static TypeProvider fail() { > return name -> Optional.empty(); > } > } > > As you can see the code is not bad but the code of chain() could be simplified > if there was a way on Optional to call a Supplier of Optional if an Optional > is empty. > Currently, orElse() takes a value, orElseGet takes a lambda that will return > a value > and there is no method that takes a lambda and return an Optional > (like flatMap but but with a supplier that will be called if the Optional is > empty). > > If we add the method orElseChain(Supplier<? extends Optional<T>> supplier) > perhaps with a better name ?, then the code of chain is better: > > public default TypeProvider chain(TypeProvider provider) { > return name -> loadType(name).orElseChain(() -> provider.loadType(name)); > } > > Am i the only one to think that this method is missing ? > > regards, > Rémi >