Pluggable type sytems

Denis Koroskin 2korden at gmail.com
Sun Feb 8 15:48:01 PST 2009


On Mon, 09 Feb 2009 01:19:55 +0300, Bartosz Milewski <bartosz at relisoft.com> wrote:

> I also believe that non-null should be the default. Most references in a  
> typical program are assumed to be non-null.
>

Oh, that's true!

> Like for every default, there should be an escape mechanism from it.  
> However, adding "nullable" to the type system might be controversial,  
> especially because it requires special treatment of constructors and  
> polymorphism (hence additional type modifiers, raw and poly-null, and I  
> haven't even mentioned wildcard annotations).
>

Common opinion is that this is worth the trouble these days. More and more people discuss, write articles on non-nullable types and incorporate them into languages. Main C# architects has stated that absence of non-nullable types by default is his greatest mistake that is too late to be fixed.

> So some time ago I came up with a more modest proposal. The compiler  
> should catch nullable references at their source. It should enforce what  
> I call "declaration is initialization" (DII). For instance, the  
> following is correct:
>
> Foo foo = new Foo;
>
> and the following is not:
>
> Foo foo; // error
> ...
> foo = new Foo;
>
> Obviously this rule is too strict, so there must be a way to override  
> it. Here's the simple syntax:
>
> Foo foo = null; // not an error!
>

And what about value types? Why special treatment for reference types only? I don't like rules like that in a language:

Foo foo; // error
int i; // okay?

If not, and this is an error, too, then this defeats the whole purpose of having T.init in D, because it will never be used per your proposal:

int i = 0; // initialized explicitly
char c = char.init; // would you use that?

> Notice that the programmer explicitly states that one should be careful  
> when using foo, because it might be null.
>
> Since this solution doesn't involve the type system, the nullability  
> doesn't propagate across function calls. But it might be a tradeoff  
> worth taking, if only for the simplicity.
>

Naah.. The whole purpose of having non-nullable types is that given a pointer you are sure it is not null:

string toString(Object o)
{
   // is it null or not? Should I check for null or not? What if it is null?
   // Should I throw? What kind of exception?
   // But was going to make it nothrow! So what, no checks?
   // Just fail with access violation? Is this the best D can do?

   return o.toString();
}

As an end user, you neglect and avoid null checks in your code ("I'm sure I won't pass null here"). And then you run your program half an hour, it segfaults with access violation and you don't have any clue where did null dereference take place. I have came across this situation so many times that I hate it.

As a library designer, you end up having null checks everywhere in your code which is some kind of a paranoia because in 99% of cases the pointer will be not null. But why put so many special case and checks if it is *disallowed* to run code with null pointer in first place? So people decided - let's enforce that at compile time! That's the whole point of the feature - disallow invalid use cases at compile time. You get cleaner code (no unnecessary null-checks and throws) and small performance improvement as a bonus.

I would like to write code as this as be sure that it will never fail:

string toString(Object o) // non-nullability is enforced at compile time
{
    return o.toString();
}

This is D style - do as much as possible at compile time - and I believe non-nullable types fit D type system very well.

> Constructors still need some special treatment. Every class member  
> variable must be initialized in the constructor. Again, the escape is to  
> _explicitly_ initialize it to null. This might seem redundant, since the  
> variable is already default initialized to null, but the compiler can  
> easily eliminate such redundancies.
>
> I also found out that Java's editor, Eclipse, enforces DII--a very  
> useful feature that paid off for me in the first 100 lines of code I  
> wrote after a long period of inactivity in Java ;-)
>
>> Michel Fortin Wrote:
>
>> In fact, I'd even argue that non-nullability should be the default for
>> pointers and class references, because it is either safer (if the
>> compiler doesn't do the null check for you) or less troublesome to use
>> (if the compiler forces you to check for null everytime). Another
>> reason being consistency: value-types can't be null by default and so
>> should be class references and pointers. And making pointers
>> non-nullable by default can only be done at the language level, so
>> obviously it's better in the language than as a user-defined type
>> modifier.
>





More information about the Digitalmars-d mailing list