unordered()

Howard Lovatt howard.lovatt at gmail.com
Tue Dec 25 12:40:09 PST 2012


I would design IntStream to have intMap and map methods, so that there is no ambiguity. I find the current cure, IntFunction not extending Function, worse than the disease!

Sent from my iPad

On 25/12/2012, at 1:43 PM, Joe Bowbeer <joe.bowbeer at gmail.com> wrote:

> 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