Loose ends: Optional

Remi Forax forax at univ-mlv.fr
Tue Jun 11 01:21:43 PDT 2013

On 06/11/2013 02:05 AM, Brian Goetz wrote:
> I got confirmation from the Fugue maintainers here.  They confirm that 
> the null behavior of map() is as intended, and also that returning 
> null from the flatMap function would be an outright bug, but they 
> chose simply to not enforce it -- but also allowed as how they liked 
> the idea of enforcing it.  So, I think what we've got is in the same 
> spirit.

I agree that we should enforce that the function used by flatMap should 
never return null.

Usually, swallowing null is not a good idea because users will expect 
that other methods will do the same
so you end up to add code that swallows null everywhere in your code base.
Furthermore, as Paul said, Stream is our main concept and findFirst 
throws a NPE if the result is null.
Choosing a different semantics than Stream.findFirst() should not be 
done gratuitously.

Let suppose we have a method foo(x) that may return null,
using the Fugue semantics, one can write
   optional.map(x -> foo(x))
if now we use the Stream semantics, our user will have to write
   optional.flatMap(Optional.fromNullable(x -> foo(x)))

so it's a matter of choosing if we want to force users to acknowledge 
that a method can return null or not.

Given that nobody read the doc (to know if the method returns null or not),
I change my mind of this and think it's fine if we add a line in the 
javadoc that said that unlike Optional.of(),
map() implementation swallows null.

> I don't follow your arguments about why flatMap "requires" 
> fromNullable, but given that this is a feature that has also been 
> widely requested, if that will bring this sad story to a close, then 
> I'm good with it.

Ok, cool.


> On 6/10/2013 3:14 PM, Brian Goetz wrote:
>>> For flatMap, the rationale for "throw on null return" here is that:
>>> Optional-returning methods should never return null (they should be
>>> total functions, they can always return either a present or empty
>>> optional), so a null return should be considered a programming error
>>> (like trying to unbox the "null" Integer.)
>>> For map, it is different; it is entirely reasonable to imagine that the
>>> mapper is a partial function, so, just like with computeIfAbsent, we
>>> should interpret a null return as "no result".
>> Looking at the Fugue implementation, it differs slightly.  Their map()
>> treats null-return as empty, and their flatMap simply returns null if
>> the mapper returns null.  I am fine with being consistent with Fugue
>> here; I think the lambda passed to flatMap should never return null, but
>> we don't have to go out of our way to check it if we don't want.
>> I've got a query into the Fugue guys to see if they're happy with that
>> after having used it for a while.

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