Round 2 feedback
brian.goetz at oracle.com
Mon Feb 11 14:06:06 PST 2013
> - We use many Maps here, with many transformations. It is still painful to
> do operations like transformValues, because it usually involves using other
> lambdas and then type inference fails, still requiring specificying the
> actual type parameters - and this might require many parameters sometimes;
Can you provide some examples? I think we've worked out most of the
type inference failures. Its possible we missed something, and its also
simply possible that b76 does not have all the latest and greatest bits.
If you provide some examples, either we can say "works in latest" (in
which case you're happy) or it may become the basis of a useful bug
> - At least here, even simple transformations such as
> requires the explicit types;
This compiles fine without explicit types using the tip.
> - groupingBy that returns a Map keyed by the Stream type is completely
> unintuitive. If not by the suggestion from the mailing list, I would never
> think of it as being applicable to my use case. A better name is certainly
groupingBy returns a Map keyed by an inferred type. For example, if you
want to group people by city, the map is keyed by City:
byCity = people.collect(groupingBy(Person::getCity)));
Seems intuitive to me -- what am I missing?
> - It seems odd to have collect and collectUnordered when some Collectors
> are naturally unordered, such as toSet. Can't it be changed to be a
> property of the Collector somehow?;
Still searching for the right way to present this one without
overloading the user with the umpteen intersecting considerations
(concurrent target vs not; ordered source vs not; ordered destination vs
not; whether order is relevant to the user; etc etc).
For now I'll just note that cases like collecting to toSet() represent a
small percentage of the cases when order is not relevant; we *can*
detect this but that doesn't relieve us of the need to provide a way for
the user to say whether he cares/doesn't care about encounter order.
> - computeIfAbsent is useful, but for most Guava cases I wanted to lambdify
> I actually needed a method that returns an Optional instead. Can it be
You mean, if the factory function returns Optional.empty(), don't insert
a mapping? Just return null when you mean "don't create a mapping".
> - Here is my greatest concern so far: parallel streams in their current
> form will cause Java EE applications to fail miserably. In such
> environments, threads cannot be freely created and all types of leaks and
> exceptions can happen if one calls a method in a non-container managed
> thread. Since calling parallelStream is cheap, I guess people will do it
> often and it will be hard for Java EE developers to find out if any
> third-party Java SE 8 code is safe to call or not - and enterprise
> developers unaware of such restrictions, which are unfortunately the
> majority, will be puzzled by never seen exceptions or erratic behaviour in
> production. My suggestion would be to add a parameter to parallelStream and
> parallel which is an abstraction to thread management, forcing people to
> think about it.
The problem is valid one, but I do not believe the proposed solution is
the right one. (Developers will make all the same mistakes as they
currently make with choosing parameters like the pool size for a
fixed-sized thread pool. They pick a number that makes sense on their
developer workstation, hardcode that, and then everyone is screwed when
it hits production.) Much better to provide the EE container with the
tools to set these on a policy basis. We're working with the EE folks
to figure out what our options are. The right answer may well be to
fall back to sequential in some cases.
> Then one can construct a wrapper over the
> container-specific API for now and Java EE 8 can provide the standardized
> - Some throw-away Javadoc could be added, especially to Collectors, only
> with sample code for a Person class so developers can understand what
> methods are supposed to do.
Documentation? What's that?
More information about the lambda-dev