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