www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - null analysis with control flow

reply w0rp <devw0rp gmail.com> writes:
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!"
Sep 21 2016
next sibling parent eugene <egordeev18 gmail.com> writes:
On Wednesday, 21 September 2016 at 13:10:53 UTC, w0rp wrote:
 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.
hello, i saw something like this in Ceylon and Kotlin
Sep 21 2016
prev sibling next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 21 September 2016 at 13:10:53 UTC, w0rp wrote:
 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.
I don't see why pattern matching would be alien. It's kind of like a super-charged switch. D's algebraic in std.variant could be used to represent a limited Option type, no?
Sep 21 2016
prev sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 09/21/2016 09:10 AM, w0rp wrote:
 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.
I've said it before, and I'm going to keep saying it: Nemerle's Algebraic's and pattern matching are freaking awesome and I wish D would outright copy it (instead of mucking with the current library solutions). THIS is how to do Algebraics: https://github.com/rsdn/nemerle/wiki/Grok-Variants-and-matching
Sep 21 2016