So, last time
I said "the invocation n.Foo()
will raise a null pointer exception", which
it will of course, but in the more complete example involving Length
no such exception could ever be
raised: the body of the while
loop was guarded by a test to determine whether current
was null. Duh.
The point is, it seems that some simple form of nullness analysis would completely eliminate the problems with null
that I talked about previously. But, I also said that such an analysis has its own problems. The thing is, this kind of
analysis isn't simple after all. Consider:
test(n) { if(n is null) return 42; else return 17; } main() { var n = null; if(test().IsPrime()) n.Blah(); }
This is a relatively simple (though convoluted) example, but it should illustrate the idea: to get "perfect" nullness
analysis in we would need to actually run the program (to determine whether the number is prime using the definition
of IsPrime
). This is something we really don't want to do (there goes any hope of a termination proof, for
one thing). What if the code needs to ask the internet whether the number is prime? All kinds of chaos.
Perhaps a better idea is a very naive nullness analysis, one that only recognizes explicit guards of the form
if(something is not null) { ... }
or similar. Under such a system, if something
had an empty typeset
(indicating that it is always null), then the body of the if
statement would not be examined.
Then, unguarded method invocations on objects with empty typesets could raise a warning.
This would yield more accurate types during inference, and would limit the number of spurious warnings. The latter aspect should be obvious, but the former might not be as clear. Consider:
main() { var n = null; var g = 42; if(n is not null) { n.Bleck(); g = new Foo(); } return g + 7; }
Let's assume that Foo
does not implement operator+
. With the simple form of nullness analysis
described above, this code typechecks correctly: g
is never assigned to an instance of Foo
, so its
typeset contains only Int[]
(which does implement operator+
). Without nullness
analysis, the invocation n.Bleck()
would generate a warning, and the expression g + 7
would generate an error. Here nullness analysis (or nullness inference, as the Nice
people call their version of it) is acting as a kind of poor-man's
dataflow analysis.
We still need to analyze such a technique for correctness. For now I'll handwave it away; I've got work to do.
No comments:
Post a Comment