Should Stream be covariant? (original) (raw)

Ali Lahijani alahijani at gmail.com
Wed Jan 30 14:23:13 PST 2013


On Thu, Jan 31, 2013 at 1:14 AM, Ali Lahijani <alahijani at gmail.com> wrote:

On Thu, Jan 31, 2013 at 12:25 AM, Brian Goetz <brian.goetz at oracle.com>wrote:

Of course it is possible to remove the invariant BinaryOperator -- it could be replaced with

BiFunction<? super T, ? super T, ? extends T> Clearly that would be less convenient in some cases, and would have some cost in API readability, since everyone knows what a BinaryOperator is but one has to read more carefully to figure out what the BiFunction is supposed to do. So I'll turn your question around to you: what benefits would we get from doing so, that would make it worth suffering the consequences of the above? To be able to do a reduce even when what you have is a mere Stream<?_ _extends T>, not a full Stream. Currently there is no type-safe way to do a seedless reduce like this: Stream<? extends CharSequence> stream = ... Optional total = stream.reduce((s1, s2) -> s1.toString() + s2.toString()); I suspect even BiFunction<? super T, ? super T, ? extends T> wouldn't solve that.

I also kind of hoped, when that elevate() method can be implemented, it could be added as an static method in Stream. That way Stream<? extends T> and Stream would be truly interchangeable. Sort of declaration-site covariance for free.

I mean one direction is already there: Stream<? extends T> is assignable from Stream. The other direction, from Stream<? extends T> to Stream can be added as a library method, if Stream becomes fully covariant.

Streams aside, I think adding static methods to Iterator, Spliterator, Iterable, etc. which do the same kind of elevation might be useful as well.

Best



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