May 19, 2013
On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:
> Sounds like a race problem unrelated to null. With non-null objects the race would have manifested itself in a different way, perhaps even more pernicious.
>

It is both a race condition and a null problem. And having non nullable type would have been a compile time error instead of days of debugging.
May 19, 2013
On 5/19/13 9:11 AM, deadalnix wrote:
> On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:
>> Sounds like a race problem unrelated to null. With non-null objects
>> the race would have manifested itself in a different way, perhaps even
>> more pernicious.
>>
>
> It is both a race condition and a null problem.

No, it's just a race condition.

> And having non nullable
> type would have been a compile time error instead of days of debugging.

No, the race condition would have stayed.


Andrei
May 19, 2013
On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:
> On 5/19/13 9:11 AM, deadalnix wrote:
>> On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:
>>> Sounds like a race problem unrelated to null. With non-null objects
>>> the race would have manifested itself in a different way, perhaps even
>>> more pernicious.
>>>
>>
>> It is both a race condition and a null problem.
>
> No, it's just a race condition.
>
>> And having non nullable
>> type would have been a compile time error instead of days of debugging.
>
> No, the race condition would have stayed.
>
>
> Andrei

I believe this claim requires an explanation:

It's a good practice to initialize references(and all other types of variables) as soon as possible - and if possible, right away in the declaration. If that reference started as null, it's safe to assume it was not possible to initialized it at declaration, so it was intentionally initialized with null(if there was no initialization Java would scream at you).

Now, let's assume that reference was non-nullable. It is safe to assume that this change would not remove the obstacle that prevented that reference from being initialized right away in the declaration - so you still need to initialize it to something else - let's call that something `Nil`. Nil is an object that tells you that the reference has not yet been initialized.

So, in the original bug the reference "could be seen
as null where it was assumed everywhere to be set.". But now we don't have null - so that piece of code that thought the reference is null would now think that it is... what? The initialization value? No! Because we didn't switch from initializing the reference with null to initializing it with the later initialization value - we couldn't do it. Instead, we had to use Nil. So now, the reference 'could be seen as Nil where it was assumed everywhere to be set'...

Now, if you are lucky and your Nil is the better-kind-of-null that is used in dynamic object oriented languages, you'll get a nil exception - which is just as good as null exception. But if you are not so lucky, and you had to declare Nil as a blank object of the type of that reference, you are going to have logical bug, which is far worse than exceptions...
May 19, 2013
On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:
> On 5/19/13 9:11 AM, deadalnix wrote:
>> It is both a race condition and a null problem.
>
> No, it's just a race condition.
>
>> And having non nullable
>> type would have been a compile time error instead of days of debugging.
>
> No, the race condition would have stayed.
>

That is ridiculous. non nullable would have made the bug non existent, and even without race condition the problem would exists. a reference is null, it container shared, then set to something else. You can put barriers all over the place to make that sequentially consistent that it wouldn't change anything and the bug would still arise.

You also never provided any convincing solution to the safety hole. We can't even add check only on some edges cases as D also have values types. The only solution we are left with that is really safe is to null check every dereference or give up on @safe.

I encourage you to look at this : http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

Most new languages removed nullable by default, or limited its uses (scala for instance, allow for null for limited scope).

I once again want to get attention on the fact that GC change everything in regard to reference, and that the C++ situation is a bad example.

Idan Arye > Nil proposal make no sens in a statically typed language. And you'll find no better kind of null. We have all tools we need in D to work around null in library.
May 19, 2013
On Sunday, 19 May 2013 at 04:57:15 UTC, Walter Bright wrote:
> On 5/18/2013 8:54 PM, deadalnix wrote:
>> On Sunday, 19 May 2013 at 01:20:31 UTC, Walter Bright wrote:
>>> I understand that. But the rationale you gave for having a default constructor
>>> was to be able to disable default construction.
>>
>> RAII or construction based on template parameters.
>
> I know what default constructors are used for in C++. That wasn't what I asked, though. I asked for compelling rationale.
>

I have bunch of code that goes like :

auto oldVar = var;
scope(exit) var = oldVar;

This is begging for a RAII solution where I pass var as template parameter but would require default constructor. This is an actual problem I have right now as all save/restore are harder and harder to keep in sync for no reason and generate a lot of boilerplate.

This is a problem I have right now that default constructor would solve, and this isn't the first time I hit that need.
May 19, 2013
On Sun, 19 May 2013 19:12:15 +0200, Idan Arye <GenericNPC@gmail.com> wrote:

> It's a good practice to initialize references(and all other types of variables) as soon as possible - and if possible, right away in the declaration. If that reference started as null, it's safe to assume it was not possible to initialized it at declaration, so it was intentionally initialized with null(if there was no initialization Java would scream at you).
>
> Now, let's assume that reference was non-nullable. It is safe to assume that this change would not remove the obstacle that prevented that reference from being initialized right away in the declaration - so you still need to initialize it to something else - let's call that something `Nil`. Nil is an object that tells you that the reference has not yet been initialized.

Uhm, no. Nononono. No. This is a complete and utter fallacy. What you
have just done is define Nullable!(NonNullable!T). I should not have to
explain too closely why this is a bad thing and should not be done.

-- 
Simen
May 19, 2013
On Sunday, 19 May 2013 at 17:35:43 UTC, deadalnix wrote:
> Idan Arye > Nil proposal make no sens in a statically typed language. And you'll find no better kind of null. We have all tools we need in D to work around null in library.

That's not the point. The point is that if you couldn't initialize this reference to null, you had to initialize it to something else, so you would still get your race condition.
May 19, 2013
On Sunday, 19 May 2013 at 17:46:13 UTC, Simen Kjaeraas wrote:
> On Sun, 19 May 2013 19:12:15 +0200, Idan Arye <GenericNPC@gmail.com> wrote:
>
>> It's a good practice to initialize references(and all other types of variables) as soon as possible - and if possible, right away in the declaration. If that reference started as null, it's safe to assume it was not possible to initialized it at declaration, so it was intentionally initialized with null(if there was no initialization Java would scream at you).
>>
>> Now, let's assume that reference was non-nullable. It is safe to assume that this change would not remove the obstacle that prevented that reference from being initialized right away in the declaration - so you still need to initialize it to something else - let's call that something `Nil`. Nil is an object that tells you that the reference has not yet been initialized.
>
> Uhm, no. Nononono. No. This is a complete and utter fallacy. What you
> have just done is define Nullable!(NonNullable!T). I should not have to
> explain too closely why this is a bad thing and should not be done.

These are the assumptions I'm working with:
 - We can't use a nullable reference
 - We can't initialize the reference upon declaration to it's real value.

The first assumption is required because we want to describe how the bug scenario deadalnix brought up would look like if references were non-nullable. The second assumption is required because if we could initialize the reference upon declaration to it's real value, we should have just done it in the first place and avoid the whole race hazard.

Now, I'm not saying the solution I presented is good - I'm trying to show that given those two assumptions, we are forced to use this bad solution.
May 19, 2013
On Sunday, 19 May 2013 at 17:51:36 UTC, Idan Arye wrote:
> On Sunday, 19 May 2013 at 17:35:43 UTC, deadalnix wrote:
>> Idan Arye > Nil proposal make no sens in a statically typed language. And you'll find no better kind of null. We have all tools we need in D to work around null in library.
>
> That's not the point. The point is that if you couldn't initialize this reference to null, you had to initialize it to something else, so you would still get your race condition.

Note that it had to be initialized, and my patch to Cayenne was simply to reorder that initialization.

The patch itself was ~5lines, and would have impossible to do with a nonnullable (except with your Nil stuff, which once again don't make any sens in a strongly type language)
May 19, 2013
On Sunday, 19 May 2013 at 18:05:03 UTC, Idan Arye wrote:
> These are the assumptions I'm working with:
>  - We can't use a nullable reference
>  - We can't initialize the reference upon declaration to it's real value.
>

If you can't initialize the value, you got to assume when you use it that it may not have been initialized and handle that case. You need either an Option (where you have to be explicit about what you do when the thing is null) or a Maybe (where null is ignored and Maybe "contaminate" every result depending on a maybe value).

> The first assumption is required because we want to describe how the bug scenario deadalnix brought up would look like if references were non-nullable. The second assumption is required because if we could initialize the reference upon declaration to it's real value, we should have just done it in the first place and avoid the whole race hazard.
>

But that is the whole point ! The damn thing should have been initialized in the first place to avoid the bug. And this should have been caught at compile time with any sane type system.

And this is the exact problem with nullable by default : plenty of stuff ends up be null is some weird situation that almost never occurs when they are assumed not to be and the program crashes. NullPointerException now return 4 millions result on google, which is probably around once per java developers.

> Now, I'm not saying the solution I presented is good - I'm trying to show that given those two assumptions, we are forced to use this bad solution.

This solution is complex, do not make any sense in a strongly typed language and don't even solve the presented case.