unordered()

Joe Bowbeer joe.bowbeer at gmail.com
Mon Dec 24 18:43:13 PST 2012


Btw, this form compiles in jdk8lambda-b69:

    Stream<Integer> is = Streams.iterate(0, i -> i + 1).map(i -> (Integer)
(i * i)).limit(25);

--Joe


On Mon, Dec 24, 2012 at 6:29 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

> Right.  This is caused by the interaction of "IntFunction extends
> Function" and the overload resolution rules.  Fixed by severing the
> extension relationship between IntFunction and Function.
>
>
> On 12/24/2012 8:01 PM, Joe Bowbeer wrote:
>
>> Continuing with Uncle Bob's FP snippet:
>>
>>      (take 25 (squares-of (integers)))
>>
>> I can code this in jdk8lambda-b69 as:
>>
>>      Function<Integer, Integer> square = (Integer i) -> i * i;
>>      Stream<Integer> is = Streams.iterate(0, i -> i +
>> 1).map(square).limit(25);
>>
>>
>> First, *note* that the following simplification won't compile because
>> the RHS creates an IntStream:
>>
>>      Stream<Integer> is = Streams.iterate(0, i -> i + 1).map((Integer i)
>> -> i * i).limit(25);
>>
>> This is a bug, right?
>>
>>
>> Now something about unordered()..
>>
>> When I add parallel() before the map() and print the result, I find that
>> the into() form creates ordered results no matter where I insert
>> unordered() in the pipeline, whereas forEach() already produces
>> unordered results.
>>
>> 1. Always ordered, regardless of unordered()
>>
>>      out.print(is.map(Object::**toString).into(new StringJoiner(" ")));
>>
>>      => 0 1 4 9 ... 441 484 529 576
>>
>> 2. Naturally unordered
>>
>>      is.forEach(i -> out.print(i + " "));
>>
>>      => 0 529 576 441 ... 9 16 1 4
>>
>> Seems weird.
>>
>> -Joe
>>
>>
>>
>> On Fri, Dec 21, 2012 at 2:13 PM, Brian Goetz <brian.goetz at oracle.com
>> <mailto:brian.goetz at oracle.com**>> wrote:
>>
>>     So, the move to a more explicit choice of merging or concurrent
>>     tabulation also reduces (heh) the need for unordered(), though it
>>     does not eliminate it completely.  (Limit, cancelation, and
>>     duplicate removal all have optimized versions if encounter order is
>>     not significant.)
>>
>>     Kevin pointed out that .unordered() is pretty easy to miss, and
>>     people will not know that they don't know about it.  One possible is
>>     to make it more explicit at one end of the pipeline or the other
>>     (the only operation that is order-injecting is sorted(), and
>>     presumably if you are sorting you really care about encounter order
>>     for the downstream ops, otherwise the sort was a waste of time.)
>>
>>     The proposed tabulator / reducer stuff makes the order-sensitivity
>>     clear at the tail end, which is a good place to put it -- the user
>>     should know whether a reduce or a forEach is what they want -- if
>>     not the user, who?  (Only the user knows whether he cares about
>>     order or not, and knows whether his combination functions are
>>     commutative or not.)  The other less-ignorable place to put an
>>     ordering opt-out is at the head; we could make things more clear
>>     with adding
>>
>>        .parallelUnorderedStream()
>>     alongside
>>        .stream()
>>     and
>>        .parallelStream()
>>
>>     The obvious implementation of parallelUnorderdStream is:
>>
>>          default Stream<E> parallelStream() {
>>              return stream().unordered();
>>          }
>>
>>     which is also the most efficient place to put the .unordered (at the
>>     head.)
>>
>>
>>
>>


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