I just assume that any extension of the already complex D type system will be met with a lot of resistance. I remember the all-out wars about const and immutable (a.k.a invariant). Even those extensions are still half-assed: the construction of immutable objects and const polymorphism issues remain.
My impression is that theoreticians and very advanced programmers love elaborate type systems. Nine-to-five programmers, which are in the majority, prefer simplicity even if the cost is reliability. Just look at the comments to my blog post. I know we have to do something about null references in D, but I'm still on the fence about how we should accomplish that. Denis Koroskin Wrote: > On Mon, 09 Feb 2009 01:19:55 +0300, Bartosz Milewski <[email protected]> > 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. > > > >
