www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Proposal : allocations made easier with non nullable types.

Daniel Keep Wrote:

 Alex Burton wrote:
 I think it makes no sense to have nullable pointers in a high level language
like D.

Oh, and how do you intend to make linked lists? Or trees? Or any non-trivial data structure?

I am not saying than null pointers should be barred - I don't think it would be possible. To implement the above, in a tree you will probably have arrays of pointers, each element of the array should be a valid pointer, and never null. To implement a linked list, I agree that a null pointer is a good implementation. You could still have the X * x = 0; pointer syntax for implementing special low level stuff like this. For the majority of uses allowing null references is not necessary.
 Saying they have no place in a language is just silly; the question
 should be whether they should be the default or not (I would contend
 that they shouldn't be.)
 In D :
 X x = new X;
 This is a bit redundant, if we take away the ability to write X x; to mean X x
= 0; then we can have X x; mean X x = new X;
 If the class has a ctor then we can write X x(32); instead of X x = new X(32);

Can I just say that I *LOATHE* this syntax? It's one thing I always despised about C++; it simply makes NO sense whatsoever. It looks like the bastard offspring of a function declaration and a function call.

Does that mean you loathe it in D now for structs too or just if it was implemented for classes ?
 The first *is* redundant, but then I wouldn't state X twice, I'd use
 "auto" (because types are almost never a single letter anyway.)  Add to
 that that the existing syntax is much more intuitive; it even reads like
 a sentence.

I think that is personal taste. The sentance starting with the word auto doesn't make much sense to me.
 As I said in the nullable types thread:
 Passing 0 or 0x012345A or anything else that is not a pointer to an instance
of X to a variable declared as X x is the same as mixing in a bicycle when a
recipe asks for a cup of olive oil.

Passing garbage to a function doesn't have any bearing on the non-nullable discussion. If you're casting random integers to pointers and passing them to functions, you reap what you sow. :)

My point was that 0 is just as much not a pointer to an instance of X as 0x012456 is (unless you are quite lucky)
 That said, passing null is more like omitting an ingredient.  Which is
 unfortunate if you're making soup and the ingredient is "water."
 There are much better, and less error prone ways to write code in a high level
language than allowing null pointers.

While I'm a strong believer in non-nullable types, I don't think null pointers are evil. They're a tool like anything else; problems only arise when you misue them. I believe they're the wrong default choice, because they don't come up in normal code, but you've got to fall over yourself to make sure they don't become an issue. Let me chip in a practical example that happened just yesterday. I'm throwing together a game prototype. Since this is C#, I don't have contracts, so I'm making judicious use of Debug.Assert calls to ensure that object references are non-null. And surprise, surprise, my program crashes with null dereference errors. I walk the stack trace back, only to discover that the null got stored at some point. So the program doesn't even crash when the problem occurs (storing a null reference in a field that shouldn't have one) it occurs later in the execution when I'm no longer able to easily determine what went wrong. Eventually, I tracked it down to one of the few places in the code that I forgot to assert the reference was non-null. It was null because Microsoft didn't bother to document that a particular "magic object" doesn't exist until a certain point.

Doesn't this prove my point ? You are littering code with Debug.Assert statements to check the assumption that pointers are non null. It is much easier to manage code where you can safely assume that all pointers point to something. If you really want to write some small subset of code with a nullable type write a little template smart pointer for it, that forces you to explicitly check if it is null before using it. Like this: struct Nullable<T> //sorry don't know D syntax for this { private: T value; public this() { value = 0; } this(T val) { value = val; } T get() { if (value is null) throw NullableTypeException("value is null") else return value; } bool isnull() { return value is null; } }; void f(nullable!X x) { x.makeACupOfTea(); //wont compile. x.get().makeACupOfTea(); //will throw if null if (!x.isnull()) x.get().makeACupOfTea(); //proper use of nullable type } Sorry about the syntax - I havent done templates in D yet (probably this says a lot about the improvements over C++). Alex
Feb 09 2009