(original) (raw)

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@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@oracle.com
<mailto:brian.goetz@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.)