Primitive streams and optional

Brian Goetz brian.goetz at oracle.com
Tue Nov 20 15:35:23 PST 2012


That still leaves us in the map.get() problem, though -- with neither of these is possible to distinguish between "I got the default because there was nothing there" and "I got the default because the stream happened to contain a value equal to the default."  

On Nov 20, 2012, at 5:56 PM, Remi Forax wrote:

> On 11/20/2012 11:48 PM, Brian Goetz wrote:
>> That's an option too, thanks for reminding me.
>> 
>> Let me turn that one around.  Would you be happy with a single min(def) method that made you choose a default value always?  Or would you find it annoying and want something else too, for the cases when you know there are elements?
>> 
>> Would you spend any time wondering what the default value should be?
>> 
>> Would you worry about how to distinguish between the case that it returns the default value and the case when the default value actually was the minimum (a la map.get())?
>> 
>> I would guess that if you had min(defVal) you'd also want another version (throwing? optional?) for the cases when some of the above bother you?
> 
> min(def) and min() that throws a runtime exception are a good combo IMO,
> but because they can be generalize to min(IntSupplier),  min(() -> def) and min(RuntimeException::new),
> i think the best combo is:
>       int min() that calls min(RuntimeException::new) by default
> and int min(IntSupplier).
> 
> anyway, I think the same design should be applied to reduce, findFirst, min, max, average, etc.
> 
> Rémi
> 
>> 
>> 
>> 
>> On 11/20/2012 5:43 PM, Tim Peierls wrote:
>>> What happened to min(int defval)? That way the library doesn't have to
>>> decide on a good default, but the user can.
>>> 
>>> --tim
>>> 
>>> On Tue, Nov 20, 2012 at 5:14 PM, Brian Goetz <brian.goetz at oracle.com
>>> <mailto:brian.goetz at oracle.com>> wrote:
>>> 
>>>    We're working through implementing the primitive specialization of
>>>    streams now.  So far, its pretty straightforward; many of the ops on
>>>    reference streams have an obvious analogue (e.g., filter, map,
>>>    forEach), and many are just not applicable (e.g., into, since there
>>>    are no primitive collections.)  There are also a number of
>>>    additional methods that make sense on primitive streams, such as
>>>    sum().  (You can see the work in progress in the lambda repo.)
>>> 
>>>    The tricky ones are the ones that return some sort of Optional.  For
>>>    sum() there is an obvious value to return if there are no elements
>>>    in the stream (zero), but for min/max/average, it would require more
>>>    distortion to avoid optionality.  We can't expect users to know a
>>>    priori whether the stream is empty.  Example:
>>> 
>>>    int firstOrderNumber
>>>       customers.flatMap(c -> /* c.orders */)
>>>                .map(o -> o.getOrderId())
>>>                .min();
>>> 
>>>    The options are:
>>> 
>>>      - throw NSEE
>>>      - make up a bad default (e.g., MAX_VALUE for min)
>>>      - return an Optional<Integer>
>>>      - return an OptionalInt
>>> 
>>>    The first two are pretty bad, and are asymmetric to the reference
>>>    streams.  Creating N new OptionalXxx classes is kind of annoying and
>>>    bloaty.  (There's an argument to be made for "Well, we're boxing
>>>    once at the end anyway, boxing twice with Optional<Integer> isn't
>>>    terrible.") Though I suspect that will be an ongoing irritant.  Are
>>>    there other "options"?
>>> 
>>> 
> 



More information about the lambda-libs-spec-observers mailing list