Brian Goetz brian.goetz at
Sat Sep 22 08:02:52 PDT 2012

> One more push for the what I still think is the most defensible
> (and simplest to explain) set of design rules:
> 1. Stream operations ignore null elements.

This interacts in an unfortunate way with a property I've been fighting 
to preserve -- size-preserving ops.  I really like that in

I know the exact size of the target and exactly where to put each mapped 
element before I start.

So I prefer to interpret your suggestion as "*may* ignore null 
elements".  So in this case, a reduction can ignore nulls, a find can 
ignore nulls, but "dense" ops can choose not to.

> 2. Each operation that can return a "nothing there" result has two forms
>     Optional<T> op(...)
>     T op(..., T defaultValueIfNone);

This gets confusing for reduce, since currently we have:

   T reduce(T base, Reducer<T>)    // trying not to upset Doug by
   Optional<T> reduce(Reducer<T>)  // saying BinaryOperator<T>

If we add a

   T reduce(Reducer<T>, T defaultValueIfNone)

the user will forever be confused between the first form and the third.

In both cases, Optional was introduced to cope not with nulls, but with 
empty inputs, but of course nulls are a pesky neither-here-nor-there 
corner case.

> Rule (1) removes the ambiguity of an Optional with value null.


> (And enables the spec for Optional to say that a present
> optional is never null.)


> Although one remaining messy part is that "Optional<double>"
> (if such a thing were legal) is basically an alias for
> existing class Double, and there seems to be no reasonable
> way to force them to be the same nominal type. My Numerics posts
> address one way to reduce impact, but I still don't see a
> general backward compatible solution.

Right, OptionalNumeric<T> means we only need one Optional primitive 
class rather than N.

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