February 15, 2009
Nick Sabalausky wrote:
> "Christopher Wright" <dhasenan@gmail.com> wrote in message news:gn7jn9$1i0e$1@digitalmars.com...
>> class Foo {
>>     void delegate()? dg;
>>     void doStuff() {
>>         if (dg) {
>>             doPart1;
>>             doPart2;
>>         } else {
>>             // some other long code path
>>         }
>>     }
>>
>>     private void doPart1() {
>>         // use dg; why should I check?
> 
> Because some other function or codepath could still accidentally be breaking your precondition convention, so you're right back to inviting hidden.

Yes, but I'm using nullable variables. I'm happy with getting a hardware exception if I try dereferencing them when they're null.

I could pass the non-nullable versions to each of these convenience functions, which works in small cases (one or two such variables) and totally eliminates the value of using member functions. Plus, that's code duplication.

As for checking every time...

It's code duplication.

It's slower than removing the checks, and the checks aren't removed in release mode.

The checks are all going to boil down to:
if (variable) { } else { assert (false); }

It's unnecessary.

It's the compiler assuming that the programmer is an idiot and not allowing the programmer to insist that they know what they're doing.

I want *warnings* about this. But I think it's going to require far too much boilerplate in complex circumstances.
February 15, 2009
"Christopher Wright" <dhasenan@gmail.com> wrote in message news:gn96qc$2aic$1@digitalmars.com...
>
> I want *warnings* about this.

Ok, now *that* I could live with (at least if we ever actually got the option to treat warnings AS warnings, but that's a whole other rant). Personally, I'd still prefer this particular thing to be an error rather than a warning (with an option to unsafe-cast it to a non-null for the rare case where the check is in an inner loop and might actually be a performance issue), but at least now I see your point.


February 16, 2009
Sorry, Jarrett.  You're right; it was uncalled for.  I was having a bad day, and that was just the straw that broke the camel's back.  My comments were slightly ambiguous, but I was still upset that trying to comment on a particular syntax or subfeature of non-nullable types results in me being chucked bodily into the "hates non-nullable types" camp.  Again.  :P

To clarify: I am, and always have been, in full support of non-nullable types, preferably by default.  What I object to specifically in this case is the requirement to always check that a nullable value is not null every time it is used.

We have hardware null-dereference exceptions for this.

Another issue is that this subthread is talking about increasingly more complicated analysis by the compiler to try and determine if a given nullable value has been checked yet or not.  I don't think this is the job of the compiler; if I have a nullable value, it's because I wanted a nullable value, and I should be ready to deal with it appropriately.

Finally, this also creates a distinction between nullable types and everything else in the type system.  For example, the following test isn't enforced by the compiler.

int a,b;
// set a and b
if( b != 0 ) int c = a / b;

Maybe it should be, but unless the compiler is -very- smart about it AND it applies to all types that have potentially "unsafe" values for a given operation, I don't want to see nullable types singled out.

  -- Daniel
February 16, 2009
Daniel Keep wrote:
> To clarify: I am, and always have been, in full support of non-nullable
> types, preferably by default.  What I object to specifically in this
> case is the requirement to always check that a nullable value is not
> null every time it is used.
> 
> We have hardware null-dereference exceptions for this.
> 
> Another issue is that this subthread is talking about increasingly more
> complicated analysis by the compiler to try and determine if a given
> nullable value has been checked yet or not.  I don't think this is the
> job of the compiler; if I have a nullable value, it's because I wanted a
> nullable value, and I should be ready to deal with it appropriately.
> 
> Finally, this also creates a distinction between nullable types and
> everything else in the type system.

I am in complete agreement with you on all these points. Nullable types (int? *) and making non-nullable the default would add huge benefits; but I think others are proposing significant complexity for very small extra gain.
February 17, 2009
Mon, 16 Feb 2009 13:26:29 +1100, Daniel Keep wrote:

> To clarify: I am, and always have been, in full support of non-nullable types, preferably by default.  What I object to specifically in this case is the requirement to always check that a nullable value is not null every time it is used.

Hmm, I think I've got your point.  The nullable types should work exactly as they work now, with the same consequences.  You don't need to check for null to dereference, and you crash if you dereference null. The non-nullable types are a separate territory.  Again, you don't need to check for null to dereference, and you never crash because there is never null.  You need an explicit run-time check to move from null to non-null territory, but that's all you need, and only when you really want it.

I think it's my favorite design so far.
February 17, 2009
On Tue, 17 Feb 2009 06:03:45 +0300, Sergey Gromov wrote:
> I think it's my favorite design so far.

i second that. this would be wonderful.
February 17, 2009
Sergey Gromov wrote:
> Mon, 16 Feb 2009 13:26:29 +1100, Daniel Keep wrote:
> 
>> To clarify: I am, and always have been, in full support of non-nullable
>> types, preferably by default.  What I object to specifically in this
>> case is the requirement to always check that a nullable value is not
>> null every time it is used.
> 
> Hmm, I think I've got your point.  The nullable types should work
> exactly as they work now, with the same consequences.  You don't need to
> check for null to dereference, and you crash if you dereference null.
> The non-nullable types are a separate territory.  Again, you don't need
> to check for null to dereference, and you never crash because there is
> never null.  You need an explicit run-time check to move from null to
> non-null territory, but that's all you need, and only when you really
> want it.
> 
> I think it's my favorite design so far.

One possible change: implicit casting with an assertion that the nullable value is not null. I'm not sure whether this is a good idea. On the one hand, it's easier for the programmer to use nullable types in that case; on the other, it encourages people not to have error handling.

I favor implicit casting, for now. It shouldn't be difficult to try it both ways.
February 18, 2009
"Christopher Wright" <dhasenan@gmail.com> wrote in message news:gnfgj6$1484$2@digitalmars.com...
>
> One possible change: implicit casting with an assertion that the nullable value is not null.

I can tell right now I wouldn't like that. That would make it far too easy to make mistakes, as it would open up a way for mistakes to circumvent the whole point of having non-nullables. If I accidentially tried to provide a nullable to something that expected a non-nullable, I'd want some sort of up-front notice so that I can either fix it or confirm "yes, I really did mean that" rather than have to hope that I'm lucky enough for the value to actually be null when I test it. An implicit cast should either "just work" with no risk of runtime-error, or be disallowed in favor of something more explicit.


February 18, 2009
Nick Sabalausky wrote:
> "Christopher Wright" <dhasenan@gmail.com> wrote in message news:gnfgj6$1484$2@digitalmars.com...
>> One possible change: implicit casting with an assertion that the nullable value is not null.
> 
> I can tell right now I wouldn't like that. That would make it far too easy to make mistakes, as it would open up a way for mistakes to circumvent the whole point of having non-nullables. If I accidentially tried to provide a nullable to something that expected a non-nullable, I'd want some sort of up-front notice so that I can either fix it or confirm "yes, I really did mean that" rather than have to hope that I'm lucky enough for the value to actually be null when I test it. An implicit cast should either "just work" with no risk of runtime-error, or be disallowed in favor of something more explicit.

I think I favor this, actually. If you don't care, you can cast manually. But the implementation difference should be miniscule.
February 18, 2009
On 2009-02-17 18:17:55 -0500, Christopher Wright <dhasenan@gmail.com> said:

> One possible change: implicit casting with an assertion that the nullable value is not null. I'm not sure whether this is a good idea. On the one hand, it's easier for the programmer to use nullable types in that case; on the other, it encourages people not to have error handling.

I think it's a good idea: good enough to be useful, simple enough to be implemented without much hassle. Once we have enough code using non-nullable, it'll be easier to evaluate the impacts of adding compile-time constrains for nullables, and whether it's worth it or not.

I wouldn't make it just like an assertion though. I'd make it something separate you can deactiave with a compiler switch, just like bound checking.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/