Is the other-kind-of-null really necessary in Nullable and Variant?
Simen Kjaeraas
simen.kjaras at gmail.com
Mon Apr 29 11:20:17 PDT 2013
On 2013-04-29, 19:57, Idan Arye wrote:
> On Monday, 29 April 2013 at 16:14:02 UTC, deadalnix wrote:
>> On Monday, 29 April 2013 at 16:02:11 UTC, Idan Arye wrote:
>>> On Monday, 29 April 2013 at 15:39:47 UTC, Simen Kjaeraas wrote:
>>>> On 2013-04-29, 17:34, Idan Arye wrote:
>>>>
>>>>> On Monday, 29 April 2013 at 12:23:04 UTC, deadalnix wrote:
>>>>>> On Sunday, 28 April 2013 at 16:33:19 UTC, Idan Arye wrote:
>>>>>>> When you use `std.typecons.Nullable` with a type that already
>>>>>>> accept `null` values, you get two types of nulls - the
>>>>>>> `Nullable`'s null state the the regular type's `null`:
>>>>>>>
>>>>>>> Nullable!string a;
>>>>>>> writeln(a.isNull()); //prints "true"
>>>>>>> a = null;
>>>>>>> writeln(a.isNull()); //prints "false"
>>>>>>> a.nullify();
>>>>>>> writeln(a.isNull()); //prints "true"
>>>>>>>
>>>>>>
>>>>>> All types should be non nullable. Problem solved.
>>>>>
>>>>> *All* types? Even object references and pointers?
>>>>
>>>> That would be nice, yes.
>>>
>>> And what would they be initialized to? When you write:
>>> Object obj;
>>> what will `obj` refer to?
>>>
>>> Also, what about the C&C++ interface? Without null values, how can you
>>> use an extern function that accepts or returns pointers?
>>
>> Data flow analysis can smash your face if you try to use that before
>> initializing it. In fact, this is already done in many languages.
>
> The point is that you are forcing ref variables to point to data, even
> in paths where there is no data for them to point to.
>
> Let's say we have something like:
>
> MyClass myObject;
> auto myVar1=DEFAULT_VALUE_FOR_MY_VAR_1;
> bool objectCreated=false;
> if(myCondition()){
> myObject=new MyClass(/*some arguments*/);
> objectCreated=true;
> myVar1=myObject.calculateSomething();
> }
> auto myVar2=calculateSomethingElse(myVar1);
> if(objectCreated){
> myObject.doSomething(myVar2);
> }
> doSomethingElse(myVar2);
>
> It would be nice to create `myObject` in the second `if`, right before
> we use it, but this is not possible, since if `myCondition` is `true`
> and we do allocate `myObject`, we need to use it to calculate `myVar2`.
> And we can't pull the call for `myObject.doSomething` to the first `if`
> either - because we need to calculate `myVar2` before we use it. So, why
> not bring the calculation of `myVar2` into the first `if` as well?
> Because we need it for `doSomethingElse`, which should be invoked
> whether or not we allocate `myObject`!
>
> As humans, we can easily see that if we didn't allocate `myObject` that
> will also mean that `objectCreated` remains false, and therefore the
> program will not enter the second `if`. I would like to see a data flow
> analysis mechanism that figures that out - and that's a simple case!
>
> If `myObject` was `int` it would be easy - we could initialize it to `0`
> at declaration. But object references are not that simple - if you take
> away `null`, what will you init `myObject` to? Remember - it needs to be
> an instance of `MyClass` or of a subclass of `MyClass`. That means that:
> a) You have to allocate memory for an object you will not use.
> b) You need to call a constructor, that might have side-effects.
> c) You end up with an object that has a meaningless state.
>
> Now, let's look at that meaningless object we created. What if `MyClass`
> has fields which are object references themselves? They can't be in the
> "uninitialized state" - I would like to see the data flow analysis
> mechanism that can follow that! So, that means we need to set them to
> meaningless objects as well.
>
> Now, consider implementing a linked list.
Now, consider the fact we have Nullable in Phobos.
--
Simen
More information about the Digitalmars-d
mailing list