null analysis with control flow
w0rp via Digitalmars-d
digitalmars-d at puremagic.com
Wed Sep 21 06:10:53 PDT 2016
null references. We hate them, they make our programs exit in
circumstances we didn't anticipate. Tony Hoare called them a
"billion dollar mistake." I've spoken about this issue in this
forum before, others have, we know this issue well.
TypeScript 2 and Swift, and some Java IDEs, implement a way of
handling null references quite elegantly. I think we can learn
from this.
https://blogs.msdn.microsoft.com/typescript/2016/07/11/announcing-typescript-2-0-beta/
The method of handling null in functional programming languages
is to represent possibly null types with an Option monad.
Accessing the references to the real values within usually
requires applying pattern matching, or by calling different
functions on Option/Maybe types for checking the references to
see if they are null and getting them out again.
Other opinions may differ than this, but I think this method of
handling the problem creates two issues.
1. Most languages (including D) do not support pattern matching.
If pattern matching was added, it would be totally alien to any
programmers coming from C, Java, JavaScript, Python, etc. This
means this method of handling null might not be adopted.
2. Changing the access patterns when a type might possibly be
null can confuse developers, and decreases the likelihood of
adoption to fix what is a really essential issue in modern
programming languages.
I believe the solution presented in TypeScript, in Swift (if you
can find it in the documentation at all), and somewhat in some
Java IDEs is much better, and much more familiar to most
programmers. I'll explain by using T? to refer to possibly null
types, and T for types which are not nullable.
As described above in the TypeScript blog, when you are handling
a possibly null reference, assuming strict checking is turned on,
you are forbidden from accessing any attributes or methods from
that reference unless you first ensure that the reference is not
null. To do this, you write an ordinary if statement or other
Boolean expression. Within the confines of the area where you
have checked for a null reference, if you say that the type is
T?, the compiler knows that the type *must* be equivalent to T,
as you have checked that the reference is not null.
Assignment of null to a type T is forbidden. Assignment to a type
T? forms a fence, which would imply an atomic fence. When a type
T is assigned to a variable of type T?, then after that line of
code, the value can be considered to be of type T. When a type T?
is re-assigned to a variable value, then the null safety checks
will be applied again, and either another assignment expression
or condition must be used before access is made.
In the case of TypeScript, you can also enforce access which
might possibly crash your program if you really want to with
x!.foo. (I personally wouldn't recommend ever doing this, but
there might be some reason why it is needed.)
I say we could consider adopting such a method of handling null
references in D. We could liberally assume for a time that any
type T is non-nulllable, and apply checks only for T?, until we
can change to some future version of D where T can never be null.
What does everyone think? Shall I write a DIP for this? Does
everyone hate this idea and want to start hiring the hitmen to
shoot me dead now?
As Andrei says, "Destroy!"
More information about the Digitalmars-d
mailing list