Non-nullable references, again
Denis Koroskin
2korden at gmail.com
Wed Dec 31 05:01:52 PST 2008
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;
More information about the Digitalmars-d
mailing list