(non)nullable types

Denis Koroskin 2korden at gmail.com
Sat Feb 14 03:39:45 PST 2009


On Sat, 14 Feb 2009 11:39:17 +0300, Nick Sabalausky <a at a.a> wrote:

> "Michel Fortin" <michel.fortin at michelf.com> wrote in message
> news:gn4pl9$1217$1 at digitalmars.com...
>> On 2009-02-13 14:01:57 -0500, "Nick Sabalausky" <a at a.a> said:
>>
>>>> Or use an existing syntax:
>>>>
>>>> Foo? foo = ...;
>>>> if (Foo value = foo) {
>>>> // value is a local variable that is only accessible if foo is not
>>>> null
>>>> } else {
>>>> // value is not accessible here
>>>> }
>>>
>>> I could live with that, but I'd prefer my suggestion because it  
>>> wouldn't
>>> require the creation of an extra label for what's essentially the same
>>> variable. With your code we'd just end up with a whole bunch of:
>>>
>>> Foo? myObj = ...;
>>> if (Foo nonnullMyObj = myObj) //etc...
>>>
>>> // or
>>>
>>> Foo? nullableMyObj = ...;
>>> if (Foo myObj = nullableMyObj) //etc...
>>>
>>> ...Which just seems unnecessary to me.
>>
>> Foo? myObj = ...;
>> if (myObj !is null)
>> {
>>     doSomethingWith(myObj);
>>     myObj = null; // should this be an error?
>> }
>>
>
> --------
> // This (a more generalized case of above)...
>
> Foo? myObj = ...;
> if(myObj !is null)
> {
>     bar1(myObj);
>     if(blah1 > blah2)
>         myObj = null; // Yes, error
>     bar2();
> }
>
> // ...would change to this...
>
> Foo? myObj = ...;
> bool turnToNull=false;
> if(myObj !is null)
> {
>     bar1(myObj);
>     if(blah1 > blah2)
>         turnToNull = true;
> }
> if(turnToNull)
> {
>     myObj = null;
>     bar2();
> }
> --------
>
>> And what about:
>>
>> Foo? myObj = ...;
>> while (myObj !is null)
>>     myObj = myObj.next;
>>
>
> --------
> Foo? myObj = ...;
> while(true)
> {
>     if(myObj.next !is null)

Dang! NullPointerException, because you never checked myObj against null

>         myObj = myObj.next;
>     else
>         break;
> }
> myObj = null; //this line optional
>
> // Or, if you don't like "while(true)",
> // you could use a "bool done" flag.
> --------
>
> With Denis's syntax, I'm not sure how the second one would be possible,  

Foo? myObj = ...;
if (Foo obj = myObj) {
    while (true) {
        if (auto next = obj.next) {
            obj = next;
        } else {
            break;
        }
    }
}

> but
> the first one would certainly be nicer. So I'm tempted to say that both
> syntaxes should be allowed...
>
> However, you do have a valid point that my syntax has a problem whenever
> assigning a possibly-null value to the original nullable variable from
> within the scope of the null-check. It can definitely be worked around,  
> but
> I am coming to realize that maybe removing a variable's nullability
> shouldn't happen implicitly unless it can also be added back implicity -
> which would require flow analysis.
>
> Between that and the difficultly of Denis's syntax handling that simple
> while loop example, I guess full-blown flow-analysis would be needed  
> after
> all in order to realistically eliminate null reference errors on nullable
> types. Dang!
>

I don't think code flow analysis the way you suggest is useful. I certainly don't want my variable types to be changed at some point after null-check.

Code flow analysis would be nice to have, but in a different way:

Foo b; // not initialized, can not be read yet

if (condition) {
    b = createFoo(42);
} else if (otherCondition) {
    b = new Foo();
} else {
    // return b; // error, b is write only
    return;
}

// b is both read/write accessible at this point





More information about the Digitalmars-d mailing list