View mode: basic / threaded / horizontal-split · Log in · Help
September 26, 2009
Null references redux
Denis Koroskin wrote:
> On Sat, 26 Sep 2009 22:30:58 +0400, Walter Bright
> <newshound1@digitalmars.com> wrote:
>> D has borrowed ideas from many different languages. The trick is to
>> take the good stuff and avoid their mistakes <g>.
>
> How about this one:
> 
http://sadekdrobi.com/2008/12/22/null-references-the-billion-dollar-mistake/ 

>
>
> :)

I think he's wrong.

Getting rid of null references is like solving the problem of dead 
canaries in the coal mines by replacing them with stuffed toys.

It all depends on what you prefer a program to do when it encounters a 
program bug:

1. Immediately stop and produce an indication that the program failed

2. Soldier on and silently produce garbage output

I prefer (1).

Consider the humble int. There is no invalid value such that referencing 
the invalid value will cause a seg fault. One case is an uninitialized 
int is set to garbage, and erratic results follow. Another is that (in 
D) ints are default initialized to 0. 0 may or may not be what the logic 
of the program requires, and if it isn't, again, silently bad results 
follow.

Consider also the NaN value that floats are default initialized to. This 
has the nice characteristic of you know your results are bad if they are 
NaN. But it has the bad characteristic that you don't know where the NaN 
came from. Don corrected this by submitting a patch that enables the 
program to throw an exception upon trying to use a NaN. Then, you know 
exactly where your program went wrong.

It is exactly analogous to a null pointer exception. And it's darned useful.
September 26, 2009
Re: Null references redux
Walter Bright wrote:
> Denis Koroskin wrote:
>  > On Sat, 26 Sep 2009 22:30:58 +0400, Walter Bright
>  > <newshound1@digitalmars.com> wrote:
>  >> D has borrowed ideas from many different languages. The trick is to
>  >> take the good stuff and avoid their mistakes <g>.
>  >
>  > How about this one:
>  > 
> http://sadekdrobi.com/2008/12/22/null-references-the-billion-dollar-mistake/ 
> 
>  >
>  >
>  > :)
> 
> I think he's wrong.
> 
> Getting rid of null references is like solving the problem of dead 
> canaries in the coal mines by replacing them with stuffed toys.
> 
> It all depends on what you prefer a program to do when it encounters a 
> program bug:
> 
> 1. Immediately stop and produce an indication that the program failed
> 
> 2. Soldier on and silently produce garbage output
> 
> I prefer (1).
> 
> Consider the humble int. There is no invalid value such that referencing 
> the invalid value will cause a seg fault. One case is an uninitialized 
> int is set to garbage, and erratic results follow. Another is that (in 
> D) ints are default initialized to 0. 0 may or may not be what the logic 
> of the program requires, and if it isn't, again, silently bad results 
> follow.
> 
> Consider also the NaN value that floats are default initialized to. This 
> has the nice characteristic of you know your results are bad if they are 
> NaN. But it has the bad characteristic that you don't know where the NaN 
> came from. Don corrected this by submitting a patch that enables the 
> program to throw an exception upon trying to use a NaN. Then, you know 
> exactly where your program went wrong.
> 
> It is exactly analogous to a null pointer exception. And it's darned 
> useful.

My assessment: the chances of convincing Walter he's wrong are quite 
slim... Having a rationale for being wrong is very hard to overcome.

Andrei
September 26, 2009
Re: Null references redux
Andrei Alexandrescu wrote:
> Walter Bright wrote:
>> Denis Koroskin wrote:
>>  > On Sat, 26 Sep 2009 22:30:58 +0400, Walter Bright
>>  > <newshound1@digitalmars.com> wrote:
>>  >> D has borrowed ideas from many different languages. The trick is to
>>  >> take the good stuff and avoid their mistakes <g>.
>>  >
>>  > How about this one:
>>  > 
>> http://sadekdrobi.com/2008/12/22/null-references-the-billion-dollar-mistake/ 
>>
>>  >
>>  >
>>  > :)
>>
>> I think he's wrong.
>>
>> Getting rid of null references is like solving the problem of dead 
>> canaries in the coal mines by replacing them with stuffed toys.
>>
>> It all depends on what you prefer a program to do when it encounters a 
>> program bug:
>>
>> 1. Immediately stop and produce an indication that the program failed
>>
>> 2. Soldier on and silently produce garbage output
>>
>> I prefer (1).
>>
>> Consider the humble int. There is no invalid value such that 
>> referencing the invalid value will cause a seg fault. One case is an 
>> uninitialized int is set to garbage, and erratic results follow. 
>> Another is that (in D) ints are default initialized to 0. 0 may or may 
>> not be what the logic of the program requires, and if it isn't, again, 
>> silently bad results follow.
>>
>> Consider also the NaN value that floats are default initialized to. 
>> This has the nice characteristic of you know your results are bad if 
>> they are NaN. But it has the bad characteristic that you don't know 
>> where the NaN came from. Don corrected this by submitting a patch that 
>> enables the program to throw an exception upon trying to use a NaN. 
>> Then, you know exactly where your program went wrong.
>>
>> It is exactly analogous to a null pointer exception. And it's darned 
>> useful.
> 
> My assessment: the chances of convincing Walter he's wrong are quite 
> slim... Having a rationale for being wrong is very hard to overcome.
> 
> Andrei

I actually side with Walter here. I much prefer my programs to crash on 
using a null reference and fix the issue than add runtime overhead that 
does the same thing. In most cases a simple backtrace is enough to 
pinpoint the location of the bug.

Null references are useful to implement optional arguments without any 
overhead by an Optional!T wrapper. If you disallow null references what 
would "Object foo;" initialize to then?

Jeremie
September 26, 2009
Re: Null references redux
Walter Bright wrote:
> It is exactly analogous to a null pointer exception. And it's darned 
> useful.

On Linux, it just generates a segfault. And then you have no idea where 
the program went wrong. dmd outputting incorrect debugging information 
(so you have troubles using gdb or even addr2line) doesn't really help here.

Not so useful.
September 26, 2009
Re: Null references redux
On Sun, 27 Sep 2009 01:08:32 +0400, Walter Bright  
<newshound1@digitalmars.com> wrote:

> Denis Koroskin wrote:
>  > On Sat, 26 Sep 2009 22:30:58 +0400, Walter Bright
>  > <newshound1@digitalmars.com> wrote:
>  >> D has borrowed ideas from many different languages. The trick is to
>  >> take the good stuff and avoid their mistakes <g>.
>  >
>  > How about this one:
>  >  
> http://sadekdrobi.com/2008/12/22/null-references-the-billion-dollar-mistake/  
>  >
>  >
>  > :)
>
> I think he's wrong.
>
> Getting rid of null references is like solving the problem of dead  
> canaries in the coal mines by replacing them with stuffed toys.
>
> It all depends on what you prefer a program to do when it encounters a  
> program bug:
>
> 1. Immediately stop and produce an indication that the program failed
>
> 2. Soldier on and silently produce garbage output
>
> I prefer (1).
>
> Consider the humble int. There is no invalid value such that referencing  
> the invalid value will cause a seg fault. One case is an uninitialized  
> int is set to garbage, and erratic results follow. Another is that (in  
> D) ints are default initialized to 0. 0 may or may not be what the logic  
> of the program requires, and if it isn't, again, silently bad results  
> follow.
>
> Consider also the NaN value that floats are default initialized to. This  
> has the nice characteristic of you know your results are bad if they are  
> NaN. But it has the bad characteristic that you don't know where the NaN  
> came from. Don corrected this by submitting a patch that enables the  
> program to throw an exception upon trying to use a NaN. Then, you know  
> exactly where your program went wrong.
>
> It is exactly analogous to a null pointer exception. And it's darned  
> useful.

I don't understand you. You say you prefer 1, but describe the path D  
currently takes, which is 2!

dchar d; // not initialized
writeln(d); // Soldier on and silently produce garbage output

I don't see at all how is it related to a non-null default.

Non-null default is all about avoiding erroneous situations, enforcing  
program correctness and stability. You solve an entire class of problem:  
NullPointerException.
September 26, 2009
Re: Null references redux
Jeremie Pelletier wrote:
> Andrei Alexandrescu wrote:
>> Walter Bright wrote:
>>> Denis Koroskin wrote:
>>>  > On Sat, 26 Sep 2009 22:30:58 +0400, Walter Bright
>>>  > <newshound1@digitalmars.com> wrote:
>>>  >> D has borrowed ideas from many different languages. The trick is to
>>>  >> take the good stuff and avoid their mistakes <g>.
>>>  >
>>>  > How about this one:
>>>  > 
>>> http://sadekdrobi.com/2008/12/22/null-references-the-billion-dollar-mistake/ 
>>>
>>>  >
>>>  >
>>>  > :)
>>>
>>> I think he's wrong.
>>>
>>> Getting rid of null references is like solving the problem of dead 
>>> canaries in the coal mines by replacing them with stuffed toys.
>>>
>>> It all depends on what you prefer a program to do when it encounters 
>>> a program bug:
>>>
>>> 1. Immediately stop and produce an indication that the program failed
>>>
>>> 2. Soldier on and silently produce garbage output
>>>
>>> I prefer (1).
>>>
>>> Consider the humble int. There is no invalid value such that 
>>> referencing the invalid value will cause a seg fault. One case is an 
>>> uninitialized int is set to garbage, and erratic results follow. 
>>> Another is that (in D) ints are default initialized to 0. 0 may or 
>>> may not be what the logic of the program requires, and if it isn't, 
>>> again, silently bad results follow.
>>>
>>> Consider also the NaN value that floats are default initialized to. 
>>> This has the nice characteristic of you know your results are bad if 
>>> they are NaN. But it has the bad characteristic that you don't know 
>>> where the NaN came from. Don corrected this by submitting a patch 
>>> that enables the program to throw an exception upon trying to use a 
>>> NaN. Then, you know exactly where your program went wrong.
>>>
>>> It is exactly analogous to a null pointer exception. And it's darned 
>>> useful.
>>
>> My assessment: the chances of convincing Walter he's wrong are quite 
>> slim... Having a rationale for being wrong is very hard to overcome.
>>
>> Andrei
> 
> I actually side with Walter here. I much prefer my programs to crash on 
> using a null reference and fix the issue than add runtime overhead that 
> does the same thing. In most cases a simple backtrace is enough to 
> pinpoint the location of the bug.

But that's a false choice. You don't choose between a crashing program 
and an out-of-control program. This is the fallacy. The problem is the 
way Walter puts it it's darn appealing. Who would want a subtly 
incorrect program?

> Null references are useful to implement optional arguments without any 
> overhead by an Optional!T wrapper. If you disallow null references what 
> would "Object foo;" initialize to then?

The default should be non-nullable references. You can define nullable 
references if you so wish. The problem is, Walter doesn't realize that 
the default initialization scheme and the optional lack thereof by using 
"= void" goes straight against his reasoning about null objects.


Andrei
September 26, 2009
Re: Null references redux
Andrei Alexandrescu wrote:
> My assessment: the chances of convincing Walter he's wrong are quite 
> slim... Having a rationale for being wrong is very hard to overcome.

Especially when I'm right!
September 26, 2009
Re: Null references redux
On Sat, Sep 26, 2009 at 5:29 PM, Jeremie Pelletier <jeremiep@gmail.com> wrote:

> I actually side with Walter here. I much prefer my programs to crash on
> using a null reference and fix the issue than add runtime overhead that does
> the same thing. In most cases a simple backtrace is enough to pinpoint the
> location of the bug.

There is NO RUNTIME OVERHEAD in implementing nonnull reference types.
None. It's handled entirely by the type system. Can we please move
past this?

> Null references are useful to implement optional arguments without any
> overhead by an Optional!T wrapper. If you disallow null references what
> would "Object foo;" initialize to then?

It wouldn't. The compiler wouldn't allow it. It would force you to
initialize it. That is the entire point of nonnull references.
September 26, 2009
Re: Null references redux
On Sun, 27 Sep 2009 01:29:55 +0400, Jeremie Pelletier <jeremiep@gmail.com>  
wrote:
> [...] I much prefer my programs to crash on using a null reference and  
> fix the issue than add runtime overhead that does the same thing.

What runtime overhead are you talking about here? Use of non-null pointers  
actually make your program run faster, because you don't have to check  
them against null all the time. Non-null references is a contract, which  
is enforced by a compiler at compile-time, not runtime. It also makes your  
program more consistent and less verbose.

>
> Null references are useful to implement optional arguments without any  
> overhead by an Optional!T wrapper.
>

Once again, what overhead are you talking about? Optional!(T) (or  
Nullable!(T)) doesn't have to have any additional bits to store the NULL  
state for reference types.

> If you disallow null references what would "Object foo;" initialize to  
> then?
>

Nothing. It's a compile-time error. But the following is not:

Object foo = initializer();
Nullable!(Object) foo2; // default-initialized to a null, same as currently
Object? foo3; // a desirable syntax sugar for Nullable!(Object)
September 26, 2009
Re: Null references redux
Andrei Alexandrescu wrote:
> But that's a false choice. You don't choose between a crashing program 
> and an out-of-control program. This is the fallacy. The problem is the 
> way Walter puts it it's darn appealing. Who would want a subtly 
> incorrect program?

Oh, I've heard people argue for them.

>> Null references are useful to implement optional arguments without any 
>> overhead by an Optional!T wrapper. If you disallow null references 
>> what would "Object foo;" initialize to then?
> 
> The default should be non-nullable references. You can define nullable 
> references if you so wish. The problem is, Walter doesn't realize that 
> the default initialization scheme and the optional lack thereof by using 
> "= void" goes straight against his reasoning about null objects.

If there was a reasonable way of having NaN values for ints, D would use 
them. So we're stuck with a less than ideal solution, which is default 
initializing them to 0. At least you get repeatable results from that, 
rather than randomly wrong ones.

"=void" is justifiable in certain optimization cases. D is, after all, a 
systems programming language with back doors there when you need them.

The problem with non-nullable references is what do they default to? 
Some "nan" object? When you use a "nan" object, what should it do? Throw 
an exception?

The problem with null references is not the canary dying, it's that 
there's a logic error in the user's code. Putting a gas mask on the 
canary keeps it from dying, but the gas is still seeping in, you just 
don't know it.
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home