Stream.flatMap signature is not correct

Remi Forax forax at univ-mlv.fr
Fri Nov 30 17:44:40 PST 2012


Stream.flatMap is currently specified as:

   <R> Stream<R> flatMap(FlatMapper<? super T, ? extends R> mapper);

but should be:
   <R> Stream<R> flatMap(FlatMapper<? super T, ? super R> mapper);

and better (R is not a result but an item of the result sent as parameter of a block (hence the super)):
   <U> Stream<U> flatMap(FlatMapper<? super T, ? super U> mapper);
with FlatMapper defined:

   public interface FlatMapper<T, U> {
     /**
      * Map {@code element} and add all of the results to {@code sink}.
      *
      * @param sink Destination for mapped elements.
      * @param element The element to be mapped.
      */
     void flatMapInto(T element, Block<? super U> sink);
}

It's better to use something else than R because otherwise the signature 
of map() and flatMap() are too similar despite working differently.

While it's a nice design, I'm not sure it's a good idea to include it 
because I don't see how the compiler will be able to infer the type of U 
(old S).

Here is an example (using the current API):
ArrayList<ClassMirror> set = 
Mirrors.forClass(Object.class).methods().flatMap(
          (block, method) -> { method.parameterTypes().forEach(block); }
      ).uniqueElements().into(new ArrayList<ClassMirror>());

I have re-implemented a small reflection API based on ASM using streams 
to see how it goes.
Here the compiler can infer the type of method easily because it's the 
type of the Stream,
but for block, I don't see how the compiler can find its type.

cheers,
Rémi



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