Proposal: Elvis and Other Null-Safe Operators
Jeremy Manson
jeremy.manson at gmail.com
Tue Mar 3 11:31:59 PST 2009
On Tue, Mar 3, 2009 at 3:58 AM, Stephen Colebourne <scolebourne at joda.org> wrote:
> Jeremy Manson wrote:
>>> The principle perceived disadvantage, however, is that it encourages,
>>> rather than discourages, the use of null values in APIs.
>>
>> I would think that the principle disadvantage would be not that it
>> encourages use of null values (which, as you point out, is fine in
>> some contexts), but that it encourages programmers not to think about
>> what happens when there is a null value.
>
> But that is exactly what already happens today. Most developers are very
> poor at thinking through the null consequences of a method - the happy
> day scenario is the one focussed on.
Right. This is bad, because much of the time, the program cannot
tolerate nulls.
>> I can easily imagine
>> programmers using this all of the time without thinking about it, and
>> then being surprised when a null ends up in the wrong place and not
>> knowing how it got there. Even with a simple example:
>>
>> public String someFunction(String a, String b) {
>> String s = a?.concat("foo");
>> String t = b?.concat(a);
>> return myHashMap?.get(t);
>> }
>>
>> Now, someFunction returns null. Is it because a was null? Or b was
>> null? Or myHashMap was null? Or there was no mapping for t in
>> myHashMap?
>
> Or perhaps it doesn't matter, and thats why the code was written that
> way. Null as 'don't know' or 'don't care' is incredibly common.
So, we have two cases:
1) I've done something wrong, in which case "." provides useful
semantics, because it is fail fast.
2) "Don't know" or "Don't care", in which case "?." doesn't provide
useful semantics, but is less typing.
Flipping through a few thousand lines' worth of our source files, I
see hundreds of examples of #1, and only a couple of examples of #2.
Most of the time, we know a priori that we're not doing a null
dereference, so we don't need the ?.. This pretty much gels with my
intuition about this. Perhaps it is different in EE code? I would be
interested to hear a more thorough study of people's source bases. If
it is true that #2 is only responsible for a tiny fraction of the
cases in general, then it is a little odd to add a programming
language feature around it.
(By the way, I'm not denying that it is, as you say, common!)
Additionally, every time you use ?., you are going to have to think
incredibly carefully about whether it is #1 or #2. And I have this
sneaking suspicion that most programmers will just sprinkle it
liberally all over their code without thinking about it at all. When
they get it wrong, that's going to make errors harder to catch. From
a design standpoint, I would lean towards forcing people to think
about it every time, because they are more likely to get it right that
way.
>> If you want to cut down on
>> extraneous if-testing, I would use JSR-305's Nullity annotations
>> instead.
>
> What does this code do when passed null?
>
> Foo f = new Foo(null);
> int v = f.value;
>
> public class Foo {
> public final Integer value;
> public Foo(@Nonnull Integer value) {
> this.value = value;
> }
> }
>
> There is a NPE at f.value, not at new Foo(null).
>
> You would think that you could never construct an instance of Foo with a
> val of null, but you can. The @Nonnull annotation doesn't have any real
> meaning unless it is checked using a tool, and javac isn't such a tool.
> This will be very confusing when you use Foo from another part of your
> application and expect the value to be non-null and get a NPE. In fact
> the @Nonnull is positvely misleading.
I think that providing warnings for these annotations is a very good
idea. That's a language change that makes some sense to me, if the
semantics can be nailed down.
> Basically, you can't rely on JSR-305. The information needs to be
> rechecked. Thus, whats the point in using it at all?!! Documentation
> perhaps? Annotations are not suitable for handling language level issues
> like nulls.
I do think that annotations are suitable for handling language level
issues, as long as they are checked. For example, @Override has been
very useful to me, because my toolchain complains when I add it and am
not overriding something.
Jeremy
More information about the coin-dev
mailing list