unordered() (original) (raw)

Brian Goetz brian.goetz at oracle.com
Mon Dec 24 18:29:59 PST 2012


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 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 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 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-experts mailing list