Stream.flatMap signature is not correct (original) (raw)

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


Stream.flatMap is currently specified as:

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

but should be: Stream 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)): Stream 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 set = Mirrors.forClass(Object.class).methods().flatMap( (block, method) -> { method.parameterTypes().forEach(block); } ).uniqueElements().into(new ArrayList());

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