Derek Parnell wrote:
On Mon, 28 Sep 2009 19:27:03 -0500, Andrei Alexandrescu wrote:

language_fan wrote:
  int min;

  foreach(int value; list)
    if (value < min) min = value;

Oops, you forgot to define a flag variable or initialize to int.min
You mean int.max :o).

  if (list.length == 0)
     throw( some exception); // An empty or null list has no minimum
int min = list[0]; foreach(int value; list[1..$])
    if (value < min) min = value;


I'm still surprised by Walter's stance.

For the purposes of this discussion...
* Null only applies to the memory address portion of reference types and
not to value types. The discussion is not about non-nullable value types.
* There are two types of reference types:
  (1) Those that can be initialized on declaration because the coder knows
what to initialize them to; a.k.a. non-nullable. If the coder does not know
what to initialize them to at declaration time, then either the design is
wrong, the coder doesn't understand the algorithm or application, or it is
truly a complex run-time decision.
  (2) Those that aren't in set (1); a.k.a. nullable.
* The standard declaration should imply non-nullable. And if not
initialized the compiler should complain. This encourages protection, but
does not guarantee it, of course.
* To declare a nullable type, use a special syntax to denote that the coder
is deliberately choosing to declare a nullable reference.
* The compiler will prevent non-nullable types being simply set to null. As
D is a system language too, there will be a rare cases that need to subvert
this compiler protection, so there will need to be a method to explicitly
set a non-nullable type to a null. The point is that such a method should
be a visible warning beacon to maintenance coders.

Priority should be given to coders that prefer safe coding. If a coder, for
whatever reason, chooses to use nullable references or initialize
non-nullable reference to rubbish data, then the responsibility is on them
to ensure safe applications. Safe coding practices should not be penalized.

The C/C++ programming language is inherently "unsafe" in this regard, and
that is not news to anyone. The D programming language does not have to
follow this paradigm.

But it doesn't have to follow the paranoid safety paradigm either. I wouldn't like two reference types and casting between the two when they're essentially the same with one having a single value that can't be set out of 4 billions possibilities. Seems like a waste to me, especially since 3 billions of these possibilities will result in the same segfault crash than that one you're trying to make illegal on nonnull types.

I'm still not ready to use D for anything, but I watch it in hope.

I'm already using D quite a lot, I don't find null vs nonnull references all that meaningful. Like walter said, you can just make your own nonnull invariant.

Here's a very, very simple wrapper, took 10 seconds to write:

struct NonNull(C) if(is(C == class)) {
        C ref;
        invariant() { assert(ref !is null); }
        T opDot() { return ref; }
}

C++ has all sort of pointer wrappers like this one, you don't see a smart pointer feature in the C++ language for the simple reason its widely used and safer. In fact letting the semantics of these pointers up to libraries allow any project to write its custom ones, and quite a lot do.

It should be the same for D, I believe its better to implement flow analysis and let the compiler warn you of uninitialized variables (which will solve most nullptr references, the other half being by NonNull!Object fields). The compiler could also provide better tools to build smart wrapper types upon (like force initialization or prevent void initialization, heck even provide a tuple of valid initializers) and let libraries write their own.

Jeremie

Reply via email to