Kasper Nielsen kasperni at
Sat Sep 22 08:57:25 PDT 2012

On Sat, Sep 22, 2012 at 5:02 PM, Brian Goetz <brian.goetz at> wrote:
>> 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.

What purpose is the first version serving anyway?
In a library of mine I'm using the following two signatures

E reduce(Reducer<E> reducer)
  Analogous to reduce(Reducer, Object) except that it will throw an
IllegalStateException if this stream contain no elements.

E reduce(Reducer<E> reducer, E base)
  returns reduction of elements in this stream, or the specified base
if the stream contain no elements

I'm throwing ISE in the first method because I usually only used it
when I knew the stream was non-empty. And it was considered an error
on my part if it was in fact empty. I would probably go with Optional
for the first method now. If I where to redesign it.

The last version is implemented using something similar to
if (array.length != 0) {
   Object reduced = array[0];
   for (int i = 1; i < array.length; i++) {
        reduced = reducer.reduce(reduced, array[i]);
    return reduced;
return base;

When I take a peek in FoldOp I see this

   U result = seedFactory.make();
   while (iterator.hasNext())
      result = reducer.combine(result,;
   return result;

Why would I ever want to reduce the seed?


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