Non-null objects, the Null Object pattern, and T.init

Michel Fortin michel.fortin at michelf.ca
Sun Jan 19 04:03:03 PST 2014


On 2014-01-19 07:56:06 +0000, Timon Gehr <timon.gehr at gmx.ch> said:

> On 01/18/2014 10:05 PM, Walter Bright wrote:
>> Aside from that, non-null is only one case of a universe of types that
>> are subsets of other types.
> 
> This is not true. The main rationale for "non-null" is to eliminate 
> null dereferences. A? in his proposal is different from current 
> nullable references in that the compiler does not allow them to be 
> dereferenced.

Actually, 'A?' would implicitly convert to 'A' where the compiler can 
prove control flow prevents its value from being null. So you can 
dereference it in a branch that checked for null:

	class A { int i; void foo(); }
	void bar(A a); // non-nullable parameter

	void test(A? a, A? a2)
	{
		a.i++; // error, 'a' might be null
		a.foo(); // error, 'a' might be null
		bar(a); // error, 'a' might be null
	
		if (a)
		{
			a.i++; // valid, 'a' can't be null here
			a.foo(); // valid, 'a' can't be null here
			bar(a); // valid, 'a' can't be null here
		}
	}

Obviously, the compiler has to be pessimistic, which means that if your 
control flow is too complicated you might have to use a cast, or add an 
extra "if" or assert. Personally, I don't see that as a problem. If I 
have to choose between dynamic typing and static typing, I'll choose 
the later, even if some time the type system forces me to do a cast. 
Same thing here with null.


> If we just had a solution for arbitrary subset types, we'd _still_ be 
> left with a type of references that might be null, but are not 
> prevented to be dereferenced.

And I left out that point while converting the example to numeric 
ranges earlier. It's an important point.


-- 
Michel Fortin
michel.fortin at michelf.ca
http://michelf.ca



More information about the Digitalmars-d mailing list