Non-nullable references, again
Don
nospam at nospam.com
Wed Dec 31 07:29:33 PST 2008
Denis Koroskin wrote:
> On Wed, 31 Dec 2008 08:37:56 +0300, Daniel Keep
> <daniel.keep.lists at gmail.com> wrote:
>
>>
>>
>> dsimcha wrote:
>>>>> 50% of the bugs that people run into today, coding with C# in our
>>>>> platform, and the same is true of Java for that matter, are probably
>>>>> null reference exceptions.
>>> Yes, but even if this is accurate, it's misleading. Very seldom are
>>> null
>>> references difficult-to-find, time-consuming bugs. Most other things
>>> in D and
>>> other languages that are designed to prevent specific classes of bugs
>>> are designed
>>> to prevent extremely aggravating, hard to track down bugs.
>>> For example, GC was invented because tracking down memory leaks is a
>>> huge PITA.
>>> Bounds checking was invented because off-by-one errors can be subtle
>>> and hard to
>>> find. Null reference errors, on the other hand, manifest themselves
>>> in a
>>> predictable way (segfaults), and if you're using the safe memory
>>> model, i.e.
>>> bounds checking, no pointers, that's about the only thing a segfault
>>> could mean.
>>> Furthermore, null checking could be added to an implementation kind
>>> of like bounds
>>> checking without changing the language spec. I haven't made up my
>>> mind fully yet,
>>> but I question whether adding lots of complexity to the language to
>>> prevent a very
>>> easy to track down class of bugs, even if it's a common one, is
>>> justified.
>>
>> I find this counterpoint to be a bit iffy. The problem with null
>> dereference problems isn't knowing that they're there: that's the easy
>> part. You helpfully get an exception to the face when that happens.
>> The hard part is figuring out *where* the problem originally occurred.
>> It's not when the exception is thrown that's the issue; it's the point
>> at which you placed a null reference in a slot where you shouldn't have.
>>
>> Yes, we have invariants and contracts; but inevitably you're going to
>> forget one, and it's that one slip-up that's going to bite you in the
>> rear.
>>
>> One could use roughly the same argument for non-null references as for
>> const: you could document it, but documentation is inevitably wrong or
>> out of date. :P
>>
>> That said, I wonder what's stopping us from implementing them today.
>> Last time I checked (admittedly, that was like a year ago) we didn't
>> have the compile-time magic necessary to completely and transparently
>> proxy any given object.
>>
>> Ideally, we should be able to do this:
>>
>> class Foo
>> {
>> void bar() { writefln("OH HAI WURLD!"); }
>> }
>>
>> NonNull!(Foo) foo = new Foo;
>> foo.bar();
>> Foo baz = foo;
>>
>> Off the top of my head, NonNull would require an opAssign,
>> opImplicitCast to the templated type, and a way to build a full proxy
>> of the underlying type.
>>
>
> You took the idea slightly wrong. The default should be non-nullable,
>
> Foo foo = null; // error
> Nullable!(Foo) foo2 = null; // ok
>
> No implicit conversion is possible from Nullable!(Foo) to Foo (unless
> one that throws an Exception on null-reference, but I believe it
> contradicts the very idea of non-null references).
>
>> It also just occured to me that this would probably break scope. Damn.
>>
>
> Scope is not broken. Quite the contrary, it goes on par with its meaning
> - scope variable can't be null-initialized (it makes no sense at least).
>
>> A nicer syntax would be appreciated, but probably isn't a
>> requirement. :)
>>
>> -- Daniel
>
> A nicer syntax is suggested (the one used by C#):
>
> Foo nonNull = new Foo();
> Foo? possiblyNull = null;
Wouldn't this cause ambiguity with the "?:" operator?
More information about the Digitalmars-d
mailing list