Nulls

Doug Lea dl at cs.oswego.edu
Sat Sep 22 09:52:57 PDT 2012


On 09/22/12 11:02, Brian Goetz wrote:
>> One more push for the what I still think is the most defensible
>> (and simplest to explain) set of design rules:
>>
>> 1. Stream operations ignore null elements.
>
> This interacts in an unfortunate way with a property I've been fighting to
> preserve -- size-preserving ops.  I really like that in
>
>    array.map(...).toArray()
>
> I know the exact size of the target and exactly where to put each mapped element
> before I start.

Dealing with possibly-sparse arrays in the Stream API
proper seems to be a stretch anyway. As I always say,
ConcurrentHashMaps and Arrays are special enough to have
their own extended APIs that let you do non-stream-y stuff
not directly accessible via Stream API.
ArrayLists are a little problematic in that while most
people treat them as dense lists, they can also be used
as sparse (partially null) arrays. I still think that
allowing a (Parallel)Array view of an ArrayList is likely
the best move.

>
> So I prefer to interpret your suggestion as "*may* ignore null elements".  So in
> this case, a reduction can ignore nulls, a find can ignore nulls, but "dense"
> ops can choose not to.

But nothing tells anyone whether they are in a dense case?
Which blows the opportunity for having a nice simple
explainable rule.

(Maybe it is the wrong precedent because of different audience,
but we got lots of brownie points in j.u.c for having some
design rules that are so consistent that some people
don't even know they know them. Like: all blocking methods have
try- and timed variants. No null elements in queues. etc.)


>
>> 2. Each operation that can return a "nothing there" result has two forms
>>     Optional<T> op(...)
>>     T op(..., T defaultValueIfNone);
>
> This gets confusing for reduce, since currently we have:
>
>    T reduce(T base, Reducer<T>)    // trying not to upset Doug by
>    Optional<T> reduce(Reducer<T>)  // saying BinaryOperator<T>
>
> If we add a
>
>    T reduce(Reducer<T>, T defaultValueIfNone)

Why would you add this method if you already have it? :-)
I didn't necessarily mean that the default argument must always be last.

-Doug




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