(non)nullable types
Yigal Chripun
yigal100 at gmail.com
Sat Feb 14 05:50:52 PST 2009
Denis Koroskin wrote:
> On Sat, 14 Feb 2009 15:42:57 +0300, Yigal Chripun <yigal100 at gmail.com>
> wrote:
>
>> Denis Koroskin wrote:
>>> 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
>>>
>>>
>>
>> can't this be done with:
>>
>> Foo b = condition ? createFoo(42) :
>> (otherCondition ? new Foo() : return);
>> // use b
>
> It solves the simplest examples, but not more complex ones, so it is not
> generic enough.
>
In what way it's not generic enough?
IMO, this is not a matter of flow analysis at all, but rather a matter
of if statement syntax.
IMO "if" needs to be expression instead of a statement.
also See http://nemerle.org/Quick_Guide#Decisions
More information about the Digitalmars-d
mailing list