I've recently convinced myself that nullability should be the exception instead of the norm. So much of the code I write in C#/D uses reference objects assuming they're non-null. Only in certain special cases do I handle null explicitly. The issue is that if any special case is missed/mishandled, it can spread to other code.
I'm also too lazy to write non-null contracts in D. They also have far less value since violations are not caught at compile time (or better yet, in my IDE as I write code). It may be as simple as having the following 3 types: T // non-nullable T? // nullable, safe T* // nullable, unsafe I'd also like to remove all default initialization in favor of use of uninitialized variable errors. Default initialization in D is cute, but it is not a solution for programmer oversight. Single-threaded code will reproducibly do the wrong thing, but may be harder to notice in the first place. The very fact that the signalling nan change has made it into D shows that people want this type of behavior! bearophile Wrote: > Found on Lambda the Ultimate blog, Void-safety in Eiffel language, another > attempt at solving this problem: > http://docs.eiffel.com/sites/default/files/void-safe-eiffel.pdf > > > I think to solve this problem a language like D can use three different > strategies at the same time. Three kinds of object references can be defined: > 1) the default one (its syntax is the shorter one, they are defined using the > like current ones) is the "non nullable object reference". Many objects in a > program are like this. The type system assures the code to be correct, you > don't need to test such references for null. As in C# the compiler keeps eyes > open to avoid the usage of uninitialized references of such kind. (this is a > situation where "good" is better than "perfect". C# seems to work well enough > in its ability to spot uninitialized variables). > 2) The second kind is the current one, "unsafe nullabile object reference", > it's faster, its syntax is a bit longer, to be used only where max > performance is necessary. > 3) The third kind is the "safe nullabile object reference". You can define it > like using the syntax "Foo? f;". It's a "fat" reference, so beside the > pointer this reference contains an integer number that represents the class. > If your program has 500 classes, you need 500 different values for it. On the > other hand usually in a program a specific reference can't be of 500 > different classes, so the maximum number can be decreased, and you can keep > at runtime sono conversion tables that convert some subsets of such numbers > into a full pointer to class info. Such tables are a bit slow to use (but > they don't need too much memory), but the program uses them only when a > reference (of the third kind) is null, so it's not a bit problem. On 64-bit > systems such numeric tag can be put into the most significant bits of the > pointer itself (so when such pointer isn't null you just need a test and a > mask, the shift is required only in the uncommon case of null). This also > means that the ma! x number of possible class instances decreases, but not so much (you can have some conversion tables to reduce such such numeric tag to 2-5 bits in most programs). When the code uses a method of a null reference of such kind the program may call the correct method of a "default" instance of that class (or even a user-specified instance). > > Do you like? :-) > > Bye, > bearophile
