Round 1 feedback
Brian Goetz
brian.goetz at oracle.com
Wed Jan 9 06:53:09 PST 2013
Thanks Michael. This is exactly the sort of experience-driven feedback
we are looking for.
> - Code reduction was significant. My co-workers who have seen the code
> liked how well lambda is going;
:)
> - There are still several constructions that require generics to be
> explicitly used, such as into(). Was not that the case, the reduction
> would have been even greater;
I presume you're talking about things like
.into(new ArrayList<>());
^ diamond
We have a few tricks up our sleeve in this department that we're trying
out, so keep your fingers crossed.
A few things:
- into() is going away. The semantics are very subtle and confusing.
We are replacing it with something more general and predictable, but
perhaps a little more bulky. The current form is likely to look like:
stream.collect(intoCollection(ArrayList::new))
stream.collect(intoList())
stream.collect(intoSet())
^really a form of reduce
> - There were two legacy methods in this code base that relied wrongly
> on double. When I changed the reduction to use parallelStream(), my
> unit tests failed miserably, since operations like sum are not
> commutative with doubles given their lake of precision. I guess this
> will bite developers out there. Somewhere in javadoc it could be worth
> mentioning how parallel execution might affect the output in this
> case;
The key criteria for parallel reduction to have the same result as
serial reduction is associativity. Unfortunately floating-point
addition on real-world computers is not associative either! This will
be documented, though it is going to be plenty easy for users to miss
this no matter what. (Plenty of developers learned "addition is
associative" in grade school and are trying hard to remain blissfully
unaware of the fact that IEEE floating point numbers don't work exactly
the same way that we were taught real numbers do back in grade school.
> - The main transformation in the code base is taking an Entity and
> turning it into a Map<T, Entity> (Maps.uniqueIndex in Guava). In the
> binary drop that was available at that time, there was no easy way of
> achieving that. Is there any now in b72?;
Yes, though names are still stabilizing. The above-mentioned collect
form (a mutable catamorphism reduce) has lots of application:
stream.collect(groupBy(Function<T,K>)) // yields Map<K,T>
stream.collect(mappedTo(Function<T,U>)) // yields Map<T,U>
The latter form is like a "join" and I think is what you want? There
are also forms where you can pass a merge function that deals with
duplicates.
> - The other main Guava uses that remained were Multimaps - and there
> were many. Any plans to support them?;
Yes! But indirectly. One reason we moved from
stream.groupBy(f)
to
stream.collect(groupBy(f))
is so that the collecting/grouping/reducing was decoupled from the
stream library itself, through an abstraction such as Reducer/Collector.
The Map type now appears as a type parameter to the Reducer/Collector,
rather than burned into the return type of groupBy. The upshot is that
Guava can add a few dozen lines of code to export Multimap-bearing
reductions/collections (or you could) and then you could do:
stream.collect(groupToMultimap(f))
and have a Guava multimap.
> - I was able to refactor parts of my code base in a way that wasn't
> practical before by using Block in method signatures. Of course it
> should be used wisely, but be ready to see this code smell spreading
> everywhere with Java 8.
Can you elaborate?
More information about the lambda-dev
mailing list