null [re: spec#]

Roman Ivanov isroman.DEL at ETE.km.ru
Sun Nov 7 07:53:42 PST 2010


On 11/7/2010 10:51 AM, Roman Ivanov wrote:
> On 11/7/2010 1:02 AM, Walter Bright wrote:
>> Jonathan M Davis wrote:
>>> Going C# or Java's route forces the programmer to initialize variables
>>> even in cases where they know that it's not necessary (which is
>>> annoying but may or may not be worth it),
>>
>> Correct. It's not that doing flow analysis is hard, it's that it's
>> impossible to do it correctly. So you wind up with wishy-washy messages
>> that p "might not" be initialized, which is what the Java compiler does
>> for this:
>>
>>   class A
>>   {
>>        public void foo()
>>        {
>>            Object p;
>>            if (m)
>>                 p = new Object();
>>            if (m)
>>                 p.toString();  // <-- p might not have been initialized
>>        }
>>        boolean m;
>>   }
>>
>> It even errors out if you write it as:
>>
>>   class A
>>   {
>>        public void foo()
>>        {
>>            Object p;
>>            if (m)
>>                 p = new Object();
>>            if (p != null)  // <-- p might not have been initialized
>>                 p.toString();
>>        }
>>        boolean m;
>>   }
>>
>> Note that the error message is on the null check! 
> 
> I know what your mean, but the example is flawed:
> 
> public void foo()
> {
>     if (m) {
>          Object p = new Object();
>          p.toString();
>     }
> }
> 
> ...
> 
> Thing is, I don't think you really _need_ flow analysis to implement
> nonnulity. The simplest way is to disallow creation of unitialized
> nonnull variables. I think it would work, but without some clever syntax
> such rule would be painful to follow for the programmers. Things like
> these would be prohibited, for example
> 
> Duck d;
> if (b)
>     d = new Duck();
> else
>     d = new DuckSubclass();
> 
> Seems like a big loss, but it really isn't.
> 
> Duck d = b ? new Duck() : new DuckSubclass();
> 
> But ternary ops are not generic, unless you chain them which is
> super-ugly. Is there nothing that can fix this? Delegates probably can:
> 
> enum Dri {  one, two, three};
> Dri s = Dri.two;
> 
> int x = {
>     if (s == Dri.one)
>         return 1;
>     else if (s == Dri.two)
>         return 2;
>     else
>         return 3;
> }();
> 
> This works. I'm not sure how efficient it is, but that would solve the
> issue with initialization without any path analysis. If there was a
> clearer, more efficient syntax for this, it would work even better.
> 
> int x = do {
>     if (s == Dri.one)
>         return 1;
>     else if (s == Dri.two)
>         return 2;
>     else
>         return 3;
> };

OF course, the code above assumes that Duck is unnulable. I didn't want
to make my own syntax for it, because it would obfuscate the example.


More information about the Digitalmars-d mailing list