February 11, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | Christopher Wright wrote:
> Or add an invariant. You know which field is null when it shouldn't be, so that should be simple enough. Or use a property rather than a field and add a contract.
A runtime check is completely different from a compile time check.
Sebastian
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> On Wed, Feb 11, 2009 at 5:23 PM, Christopher Wright <dhasenan@gmail.com> wrote:
>> Or add an invariant. You know which field is null when it shouldn't be, so
>> that should be simple enough. Or use a property rather than a field and add
>> a contract.
>>
>> This covers the same cases that non-nullable types do, though admittedly
>> with slightly less granularity.
>>
>> A complex datastructure might have a complex initialization process that is
>> best spread across a few lines of code rather than happening all at once. If
>> that is the case, you *can't* use non-nullable types, because that
>> restriction isn't valid until the object is fully initialized. But you can
>> still use contracts here.
>
> What is your response to the part of my post that was cut off? You
> know, the part about having to write stupid contracts and how the
> compiler can and should be checking this kind of thing?
You'll eventually need to convert between nullable(T) and not_nullable(T). This requires runtime checks. A struct NotNull(T) could do the same, with some significant disadvantages.
But making not_nullable the default, I'm not sure how much work that would add for me. I know it would add a fair bit for Walter. Having it as an option and not the default would probably make it sufficiently annoying that people would not use it, in which case it's no better than adding an invariant.
On the one hand, not_nullable by default would probably do me no good. On the other, it would cost me little effort in most cases, most likely, unless I got sufficiently annoyed at all the little cases that I gave up and made every variable nullable by default.
It would be cool if we could accompany these discussions with sample compilers that implement the feature in question. That way, I could speak with some certainty when I said that a proposed feature would be annoying.
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | On Wed, Feb 11, 2009 at 8:05 PM, Christopher Wright <dhasenan@gmail.com> wrote: > > You'll eventually need to convert between nullable(T) and not_nullable(T). > This requires runtime checks. A struct NotNull(T) could do the same, with > some significant disadvantages. And how is that any different than how it is now? Currently you do "if(blah is null) do one thing; else do something else;". This kind of pattern can actually be picked up by the compiler and it would say "hey, blah is null in the first clause but I know it's not null in the second." I think Andrei mentioned this as "flow-dependent typing"? Or something like that. The "if(auto blah = something) ... else ..." pattern also fits very nicely with nullable references. > But making not_nullable the default, I'm not sure how much work that would add for me. I know it would add a fair bit for Walter. Having it as an option and not the default would probably make it sufficiently annoying that people would not use it, in which case it's no better than adding an invariant. If anything, most of your code would probably just go on working as it has. The few cases where you actually allow null, you'd have to annotate the type, and the compiler would be able to do flow-dependent typing in a vast majority of the cases. In the other cases, where you don't expect null (and forgot to check for it), the compiler will happily point out when you're a moron and pass null to a non-null parameter. > On the one hand, not_nullable by default would probably do me no good. On the other, it would cost me little effort in most cases, most likely, unless I got sufficiently annoyed at all the little cases that I gave up and made every variable nullable by default. Except honestly, the number of cases where you _don't_ want something to be null far outweighs the number of cases where you _do_. It's not exactly as insidious as the "throws" clause. > It would be cool if we could accompany these discussions with sample compilers that implement the feature in question. That way, I could speak with some certainty when I said that a proposed feature would be annoying. It would, wouldn't it! That would be nice if we had a nice compiler that we could modify and compile into an EXE. Like DMD. FFS. | |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sebastian Biallas | Sebastian Biallas wrote:
> Christopher Wright wrote:
>> Sebastian Biallas wrote:
>>> Christopher Wright wrote:
>>>> Oh, and I vote no. I think it's needless complexity. I code without any special care for null objects, and I get a segfault or NullReferenceException maybe once a week, probably less. I've always been able to track down the bug very quickly.
>>>
>>> That misses the point completely. It's not about you (as the programmer) getting NPEs; it's about the user getting bug-free software in the first place.
>>>
>>> In most cases a segfault/NPE is easy to track down for the programmer, I guess nobody would object to this. But once the software is shipped, it's a very serious problem: It's a situation the programmer didn't thought about so you usually have a data loss.
>>
>> Your language features should get rid of bugs that are easy to make and difficult to track down. It's not worthwhile to alter your language to remove easily found, easily fixed bugs.
>
> Once your software is running, an easy to fix bug is just as bad as an hard to fix bug. It's a bug after all.
>
> Of course, you can ask the question whether it's worthwhile to alter the language. Well, for D this is still possible, while other languages will have NPEs till the end of the world.
>
>> Logic errors are difficult to find. Your language cannot help you eliminate those (though contracts and unittests can help you find them).
>
> "We shouldn't try to avoid bugs of type A because we can't avoid bugs of type B" is a logical fallacy.
>
>> If you do not test your software extensively, you will ship software with logic errors. The testing required to find logic errors will also find low-level errors like segfaults.
>
> Uh.... sorry, but reality proves you wrong. I (and the rest of the world) get NPE in various kinds of extensively tested software.
>
> And we can get rid of *all* these errors by a simple language change (A change that should have been done centuries ago). This is a case where you can automatically proof correctness of a specific detail of your software. A chance that shouldn't be ignored because, uh, it's an easy to fix bug (If your rocket to the moon explodes because of an easy to fix bug, well, I don't think that is helps you that it was at least an easy to fix bug).
Agreed. NPE are normally an easy to fix, easy to diagnose bug, but it can be *extremely* difficult to trigger a case when it occurs.
Thus, trigger a run-time assert does not help AT ALL. Only a compile-time check will do.
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | On Thu, 12 Feb 2009 05:53:10 +0100, Don wrote:
> Thus, trigger a run-time assert does not help AT ALL. Only a compile-time check will do.
i couldnt agree more. i think this would be a great addition to D.
if the syntax for dealing with nullables is kept simple, i dont see any
downside.
Foo? f = getFoo();
f.doStuff(); // shouldnt compile
if (f) f.doSomething(); // automatically usable
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | > Thus, trigger a run-time assert does not help AT ALL. Only a compile-time check will do.
I wouldn't mind if the compiler only inserted assert()s for me. Having to write these assert()s all over _and_ to write the documentation comments, that a parameter must not be null, is the most annoying thing. Doing it at runtime could save us from very annoying compiler behavior, and also simplifies the compiler implementation. (Wasn't D supposed to be simple for the compiler writer? It seems everyone forgot that, even Walter.)
By the way, I wouldn't suggest to make non-null the default. This would probably be too big of a language change. Instead, I'd propose to explicitly mark non-nullable reference with "!" (similar to "?").
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> Except honestly, the number of cases where you _don't_ want something
> to be null far outweighs the number of cases where you _do_. It's not
> exactly as insidious as the "throws" clause.
I see what you're saying, though I'm certain there is a large minority of cases in which I do want to allow nulls. I really want to see how painful it would be to have non-nullable types by default.
There's also the matter of, can I use a nullable variable like a normal variable? For example:
nullable Foo foo = something;
foo.doStuff();
Brian mentioned having to check if the variable is null before using it. This would not be easy to implement, and it might be a bit hard to use. Again, I'd have to see it in use.
While we're talking about hacking the compiler, how about const by default? :P
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | > While we're talking about hacking the compiler, how about const by default? :P
This would foil all my plans to ignore or actively circumvent the new const features. It's already very annoying to cast the string literals to the good old char[].
| |||
February 12, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to grauzone | "grauzone" <none@example.net> wrote in message news:gn18a4$2c9c$1@digitalmars.com... >> Thus, trigger a run-time assert does not help AT ALL. Only a compile-time check will do. > > I wouldn't mind if the compiler only inserted assert()s for me. Having to write these assert()s all over _and_ to write the documentation comments, that a parameter must not be null, is the most annoying thing. Doing it at runtime could save us from very annoying compiler behavior, and also simplifies the compiler implementation. > > (Wasn't D supposed to be simple for the compiler writer? It seems everyone forgot that, even Walter.) > I've been wondering about that too, as I certainly see the value in easy-parsing. However, whenever the ideals of "better error prevention" and "easy parsing" collide, I would much rather see the priority placed on "better error prevention". And I especially don't want to see a potential compile-time error left as a run-time error just for the sake of easier parsing. If easy parsing was my biggest concern, I'd just use an early version of ECMAScript (and I hate ECMAScript, especially the earlier versions). > By the way, I wouldn't suggest to make non-null the default. This would probably be too big of a language change. Instead, I'd propose to explicitly mark non-nullable reference with "!" (similar to "?"). Another one of the points of D (unlike C++) is to avoid being buried under poor language design choices by not being afraid to break backwords compatibility when it's the only way to fix a problem in the language's design. I'm convinced that D hasn't reached a point where making nun-nullable the default would be too much of a problem. | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | On Thu, 12 Feb 2009 08:41:54 -0500, Christopher Wright wrote:
> Brian mentioned having to check if the variable is null before using it. This would not be easy to implement, and it might be a bit hard to use. Again, I'd have to see it in use.
after a bit of thought i dont think theres much/any benefit of forcing a check. if nonnullable was the default then using a nullable version is expected to be unusual and potentially unsafe.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply