May 19, 2013
On 5/18/2013 9:06 PM, Jonathan M Davis wrote:
> The closest that there is is
> C++'s references, which aren't rebindable and in many ways act more like
> aliases than pointers.

You can trivially create null references in C++:

int* p = NULL;
int& r = *p;
May 19, 2013
On Saturday, May 18, 2013 21:30:57 Walter Bright wrote:
> On 5/18/2013 9:06 PM, Jonathan M Davis wrote:
> > The closest that there is is
> > C++'s references, which aren't rebindable and in many ways act more like
> > aliases than pointers.
> 
> You can trivially create null references in C++:
> 
> int* p = NULL;
> int& r = *p;

Yes, but they're designed with the idea that they're non-nullable. You can't assign NULL to them or check if they're NULL. It's just that it's possible to make them NULL by the trick that you just showed. Really, it's an example of how C++ references are more like aliases than pointers (much as they're pointers underneath the hood). All around, they're a bad example of a non- nullable pointer even though that's kind of what they're supposed to be in principle.

- Jonathan M Davis
May 19, 2013
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 know that some languages have a special syntax for non-null pointers. I
>> disliked this solution for D because non-nullable pointers are just one
>> instance of creating a type with a limited set of values. Why not go for a
>> general solution? Why not create a mechanism where a type can be defined that
>> can only consist of prime numbers, for example? Why not ranged integer types?
>
> Actually most languages does the reverse. They have non nullable type, and
> provide Nullable/Option/Maybe/whatever to allow for nullable type. It allow to
> ensure that null don't pops up in unexpected places, and that null must be
> handled when it is an option.

Can you list some of those languages?


> The current solution is to rely on faith, and I remember someone talking about
> that at DConf recently.

Rely on what faith?


> Now that what other languages does is cleared, let's do some consideration on null.
>
> A pointer point on something. For instance, an int* point on an integer. null
> doesn't point on a integer. Non nullable pointer aren't a restricted set of
> values, as, by definition, null isn't a value that point to an int. That doesn't
> stand either.

By definition? Pointer semantics are what we choose it to mean.


> D already have thing like Nullable in the standard lib. Introducing Maybe is
> also pretty easy. Adding NonNullable in addition to Nullable sound like
> something is not quite right.

Nullable is something different - it exists to give a 'null' value to things that don't have a null representation, like an int.

C#, for example, has a Nullable type constructor, but it still has object references that can be null. C# has no standard way to produce a non-nullable object reference.

There's no non-null wrapper in Java, either.

> The benefit we get from null, ie having a default initialization for everything,
> is moot if @disable this() is introduced, so it is questionable at this point
> how useful it really is except as make up over current implementation deficiencies.

It's not fundamentally different from other schemes to prevent any default initialization.


> Finally it has to be added that null cause holes in @safe in ways that are
> difficult to impossible to solve.

I presume you are talking about objects bigger than 64k. It is a problem, and we'll have to deal with it, but a rare one.

May 19, 2013
On 5/18/2013 9:42 PM, Jonathan M Davis wrote:
> On Saturday, May 18, 2013 21:30:57 Walter Bright wrote:
>> On 5/18/2013 9:06 PM, Jonathan M Davis wrote:
>>> The closest that there is is
>>> C++'s references, which aren't rebindable and in many ways act more like
>>> aliases than pointers.
>>
>> You can trivially create null references in C++:
>>
>> int* p = NULL;
>> int& r = *p;
>
> Yes, but they're designed with the idea that they're non-nullable. You can't
> assign NULL to them or check if they're NULL. It's just that it's possible to
> make them NULL by the trick that you just showed.

I don't even think it's a trick, as it can easily happen unintentionally.

> Really, it's an example of
> how C++ references are more like aliases than pointers (much as they're
> pointers underneath the hood). All around, they're a bad example of a non-
> nullable pointer even though that's kind of what they're supposed to be in
> principle.
>
> - Jonathan M Davis
>

May 19, 2013
On Saturday, May 18, 2013 22:04:08 Walter Bright wrote:
> On 5/18/2013 9:42 PM, Jonathan M Davis wrote:
> > On Saturday, May 18, 2013 21:30:57 Walter Bright wrote:
> >> On 5/18/2013 9:06 PM, Jonathan M Davis wrote:
> >>> The closest that there is is
> >>> C++'s references, which aren't rebindable and in many ways act more like
> >>> aliases than pointers.
> >> 
> >> You can trivially create null references in C++:
> >> 
> >> int* p = NULL;
> >> int& r = *p;
> > 
> > Yes, but they're designed with the idea that they're non-nullable. You can't assign NULL to them or check if they're NULL. It's just that it's possible to make them NULL by the trick that you just showed.
> 
> I don't even think it's a trick, as it can easily happen unintentionally.

Yes, but it's not something that would be done intentionally, and it's something that surprises most people. I expect that the vast majority of C++ programmers would think that it's impossible before it was explained to them. C++ references are usually sold as being non-nullable, and this is arguably a hole in their design.

- Jonathan M Davis
May 19, 2013
On Sun, 19 May 2013 06:57:16 +0200, Walter Bright <newshound2@digitalmars.com> wrote:

>> The current solution is to rely on faith, and I remember someone talking about
>> that at DConf recently.
>
> Rely on what faith?

void foo(int* p) {} // p must never be null
void foo(NotNull!(int*) p) {}

One of these is tested at compile time, *and* includes valuable
documentation in the signature. The other is either less performant
or buggy.


>> Now that what other languages does is cleared, let's do some consideration on null.
>>
>> A pointer point on something. For instance, an int* point on an integer. null
>> doesn't point on a integer. Non nullable pointer aren't a restricted set of
>> values, as, by definition, null isn't a value that point to an int. That doesn't
>> stand either.
>
> By definition? Pointer semantics are what we choose it to mean.

Of course. But which definition is saner:

  "T* is either a valid pointer to a T, or a value that blows up when used
  in certain ways (but not others)."

or

  "T* is a valid pointer to T."

Of course, the latter also requires something like Maybe!T:

  "Maybe!T is either a valid pointer to a T, or a value on which no
  operations may be performed. In order to gain access to the T, both
  cases have to be handled."

-- 
Simen
May 19, 2013
On Sun, 19 May 2013 02:32:49 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Sunday, May 19, 2013 02:22:43 Simen Kjaeraas wrote:
>> Or... possibly, the current holes in @disable are fixed, and NonNull!T
>> becomes the default, because we tell people to always use them, rather
>> than flail our arms and behave like idiots. ("regular pointers are
>> broken, use NonNull!T" is a pretty good argument if it's true)
>
> I've never understood why so many people feel that nullable pointers are a
> problem. Clearly, many people do, but personally, I've rarely had problems
> with them, and there are plenty of cases where not being to make a pointer
> null would really suck (which is why we're forced to have
> std.typecons.Nullable for non-reference types). I'm not arguing against having
> non-nullable pointers, but I'd probably almost never use them myself, as I
> really don't think that they'd be buying me much. In my experince, problems
> with null pointers are extremely rare and easily caught.

My experience is the complete opposite - I think maybe 20% of bugs at my job
are caused by null references. But as you say, they are very easily fixed.

That said, two things to consider:

How many of the functions you write actually need to accept nullable
pointers/references?

If non-nullable was the default, how often would you explicitly ask for a
nullable pointer/reference?

-- 
Simen
May 19, 2013
On 05/19/2013 06:57 AM, Walter Bright wrote:
>> D already have thing like Nullable in the standard lib. Introducing
>> Maybe is
>> also pretty easy. Adding NonNullable in addition to Nullable sound like
>> something is not quite right.
>
> Nullable is something different - it exists to give a 'null' value to
> things that don't have a null representation, like an int.
>

Type Object ought not to have a "null representation" either.

> C#, for example, has a Nullable type constructor, but it still has
> object references that can be null. C# has no standard way to produce a
> non-nullable object reference.
>
> There's no non-null wrapper in Java, either.

This limits those languages' static type safety as much as D's.
May 19, 2013
On Sunday, 19 May 2013 at 12:06:01 UTC, Simen Kjaeraas wrote:
> My experience is the complete opposite - I think maybe 20% of bugs at my job
> are caused by null references. But as you say, they are very easily fixed.
>

Sometime they are super freaking hard. I have a horror story debugging Apache Cayenne : http://cayenne.apache.org/ because it was throwing NPE on a race condition that would never show up once the code is instrumented.

A reference was null for a short moment and then set to something. Due to concurrency, in extreme cases it could be seen as null where it was assumed everywhere to be set.

> That said, two things to consider:
>
> How many of the functions you write actually need to accept nullable
> pointers/references?
>
> If non-nullable was the default, how often would you explicitly ask for a
> nullable pointer/reference?

Not that much and I'd rather be warned when it is the case.
May 19, 2013
On 5/19/13 8:55 AM, deadalnix wrote:
> On Sunday, 19 May 2013 at 12:06:01 UTC, Simen Kjaeraas wrote:
>> My experience is the complete opposite - I think maybe 20% of bugs at
>> my job
>> are caused by null references. But as you say, they are very easily
>> fixed.
>>
>
> Sometime they are super freaking hard. I have a horror story debugging
> Apache Cayenne : http://cayenne.apache.org/ because it was throwing NPE
> on a race condition that would never show up once the code is instrumented.
>
> A reference was null for a short moment and then set to something. Due
> to concurrency, in extreme cases it could be seen as null where it was
> assumed everywhere to be set.

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.

Anyhow, this discussion should have finality. We could go on forever arguing the usefulness or lack thereof of non-nullable references. They didn't catch up in some languages and did in some. My personal opinion is "nice to have, but not greatly compelling".

It's reasonable to assume no major language changes will accommodate non-null references, so the next best thing would be to focus on a library solution. As Walter said, a library solution has the perk of allowing other interesting restricted types.


Andrei