Loose ends: Optional -> CompletableFuture -> Eventual

Doug Lea dl at cs.oswego.edu
Thu Jun 27 09:43:35 PDT 2013

On 05/24/13 15:20, Brian Goetz wrote:
> Proposed spec for methods on Optional, which would have the obvious counterparts
> in Optional{Int,Long,Double}.
> ...
>      public Optional<T> filter(Predicate<T> predicate)
>      public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
>      public<U> Optional<U> flatMap(Function<? super T, ? extends Optional<U>>
> mapper) {

When this flew by, I made a mental note that when it played out,
I'd have to figure out consequences for CompletableFuture.
I was just reminded by someone that now would be a good time.
A few weeks ago would have been a better time. Sorry that it
slipped my mind.

Context: Last fall, during (a lot of) discussion on concurrency-interest,
we had nearly the same requests for CompletableFuture,
but ended up with a different scheme. In part just gratuitously
different. When these methods were not in Optional, we could
pretend that things were basically consistent. But not now.
So I think we are pretty much forced to change CompletableFuture
to support the same usages in the same way.

The least kludgy way is to share an interface. Which I'm
even in favor of, because it addresses a related request
of having some read-only-ish view on top of CompletableFuture,
that we had put off due to lack of consensus. But the recent
changes to Optional almost force a consensus.

Here's one possible form with almost no impact on Optional
and relatively low impact on CompletableFuture.

Any thoughts on this before I try further fleshing out?
Remember that no one would be forced to use the top-level
unifying interface, and few constructions probably would. But still
seems necessary.

interface Eventual<T> {
     public T get();
     public boolean isPresent();
     public Eventual<T> whenPresent(Consumer<? super T> consumer);
     public Eventual<T> filter(Predicate<? super T> predicate);
     public<U> Eventual<U> map(Function<? super T, ? extends U> mapper);
     public<U> Eventual<U> flatMap(Function<? super T, ? extends Eventual<U>> 

// An Optional is ready now or never
public final class Optional<T> implements Eventual<T> {
   // change ifPresent to whenPresent, or add whenPresent as synonym

// A CompletableFuture may be ready sometime
public class CompletableFuture<T> implements Eventual<T>, Future<T> {
   // adds the various async versions
   // thenCompose either reworked into flatmap, or kept with flatMap added
   // thenAccept -> whenPresent
   // various other small adaptions, lincluding easy ones like:
   boolean isPresent() { return isCompleted(); }


More information about the lambda-libs-spec-experts mailing list