Primitive streams and optional
David M. Lloyd
david.lloyd at redhat.com
Wed Nov 21 07:02:20 PST 2012
On 11/20/2012 08:40 PM, David Holmes wrote:
> On 21/11/2012 8:56 AM, 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?
>
> Yes. min() throws; min(defVal) doesn't.
>
>>
>> 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),
>
> Aside:: are we really allowing Foo::new as a "method" reference for a
> no-arg constructor? If so I think I'd prefer Foo::Foo.
Isn't the point of the Factory<> interface to not have to do this? Or
did I dream that?
> David
> -----
>
>
>> 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"?
>>>>
>>>>
>>
--
- DML
More information about the lambda-libs-spec-observers
mailing list