Nulls

Remi Forax forax at univ-mlv.fr
Sat Sep 22 05:25:30 PDT 2012


On 09/22/2012 02:00 PM, Doug Lea 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.
> 2. Each operation that can return a "nothing there" result has two forms
>    Optional<T> op(...)
>    T op(..., T defaultValueIfNone);

The main issue with rule 1 is that the JDK already uses meaningful null,
by example, a class with a null classloader doesn't mean that there is 
no classloader.

   List<Class<?>> list = ...
   Maps<Class<?>, ClassLoader> classLoadedMap =
     list.mapped(Class::getClassLoader).into(new HashMap<>());

so Optional should be able to store null.

rule 2 is in my opinion a good compromise if by default the method that 
returns
an Optional is written using the method that takes a default value as 
last parameter.

Rémi

>
> Notes:
>
> Rule (1) means that stream.forEach(action) must be implemented as
>    x = getNextElement(); if (x != null) action.apply(x)
> and so on. As I mentioned, it would arguably be better to require
> that Streams themselves never produce nulls, but this can't be done
> without losing the ability to rely on iterators for existing collections.
>
> The only argument I know against this rule is that it can have the
> effect of delaying any consequences of using an element that should
> have been nonnull but was null due to a programming error.
> I'm sympathetic, but I think that burdening Streams with
> this is misdirected: Early detection of such errors is one
> reason why (dense) collections themselves shouldn't allow nulls.
> If people have chosen to use collections allowing nulls,
> they have already made a choice about this.
>
> Rule (1) removes the ambiguity of an Optional with value null.
> (And enables the spec for Optional to say that a present
> optional is never null.)
>
> Rule (2) enables fluent styles without requiring them.
> This reflects the fact an "Optional" type is required
> only in languages that support "value types" that can never be null.
> This includes Java, but only for primitive types. However,
> some types (like String) act so much like value types that
> using this style is appropriate. As an unrelated byproduct,
> Optional supports more fluent expression-y style that some people
> love so much they cannot otherwise cope, and others want to
> at least sometimes use. My guess is that once some of the
> newness of fluency wears off, most people will be in the
> second group, so will want multiple options.
>
> The other (default arg) method form applies in contexts where null
> (or here, extended to arbitrary default values) returns have
> their traditional meanings without forcing an unneeded
> second level of wrapping. This in part reflects the fact that
> Optional and boxing are essentially the same idea, and so
> an optional around a box is just pure wasted overhead that
> conscientious developers may wish to avoid. (During Java5
> development, some people thought that boxing overheads weren't
> important enough to provide systematic alternatives to. As it
> turns out, they were very wrong. We can at least profit
> from the lessons learned here.)
>
> Finally, among the best arguments for these rules is that they
> apply equally well to value types (primitives, plus any future
> compound value types). So any API conforming to them has a chance
> of being specialized in its entirely to, say, streams of doubles.
> Although one remaining messy part is that "Optional<double>"
> (if such a thing were legal) is basically an alias for
> existing class Double, and there seems to be no reasonable
> way to force them to be the same nominal type. My Numerics posts
> address one way to reduce impact, but I still don't see a
> general backward compatible solution.
>
> -Doug
>



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