On Oct 9, 2015, at 8:46 AM, Roger Riggs <roger.ri...@oracle.com> wrote:
> 
> The primary purpose of the existing 'requireNonNull' methods is to check for 
> null
> and throw an exception. It is used for explicit testing and producing a 
> cogent exception.
> Returning the value was a secondary benefit that allowed it to be used in 
> fluent expressions.

As I noted before, the stated purpose of "requireNonNull" can be slightly 
widened to check for null, and either throw an exception or return an 
alternative non-null value.  This is a compatible change.

Meanwhile, I just realized (after working on code in an IDE) that we already 
have this API point:

boolean nonNull(Object x) { return x != null; }

The new proposed name "nonNullElse" would seem on first glance to be a 
variation on that API point, but it's very different, since it returns T 
instead of boolean.  It seems to me that the prefix "nonNull" is already taken, 
and we have added an incompatible method to that family.        
The new API point "nonNullElse" is much closer in meaning to "requireNonNull", 
as noted before:

T nonNullElse(Object x, Object y) { return x != null ? x : y; }

T requireNonNull(Object x) { return x != null ? x : throw … }

Having different overloadings of the same name confuse T and a primitive type 
(boolean) is a known anti-pattern.  (Cf. List.remove(int|T).)  In this case, 
the names differ but "nonNull" and "nonNullElse" are going to be viewed 
together often as a group.  They are presented together in an IDE completer.  
When I complete a name, I usually have in mind what I want it to return.  
Therefore, the completion of "Objects.notN*" will show me a boolean-valued and 
a T-valued result, one of which is not what I want.  Meanwhile, if I were to 
complete "Objects.req*" I would get a choicer of T-valued operators, but not 
one particular one that I might want ("notNullElse").

As I said to you verbally, I'm not going to "die on this hill", but I do think 
the name chosen has some disadvantages that could have been avoided with a very 
slight mental shift about require.  I.e., "requireNonNull*" requires its 
*return value* to be not-null, so if its *argument* is null, then an adjustment 
is made (throw, select alternate value, get-from-supplier).

— John

Reply via email to