February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian | "Brian" <digitalmars@brianguertin.com> wrote in message news:gn3dfn$2lp3$1@digitalmars.com... > 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. I don't see much of a point in not forcing a check. I can't think of a case where it would be useful or desirable to use a nullable type without first checking for null (except for passing it to a func that takes a nullable as a param or assigning it to another nullable of the same type, but presumably the check wouldn't be required in those cases). So it may as well be forced (when dereferencing and converting to non-nullable), since you'd never really want/need to do otherwise. Even if the compiler simplified the process by only accepting the exact pattern of "if(x !is null)...", and didn't do any fancier analysis than that, I would still consider that accptable since, as you said, it would be a non-standard use. So therefore, a (very) minor inconvenience like that would be acceptable, particularly considering it would essentially guarantee no null reference errors (aside from manual use of pointers, of course). | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote:
> "Brian" <digitalmars@brianguertin.com> wrote in message news:gn3dfn$2lp3$1@digitalmars.com...
>> 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.
>
> I don't see much of a point in not forcing a check. I can't think of a case where it would be useful or desirable to use a nullable type without first checking for null (except for passing it to a func that takes a nullable as a param or assigning it to another nullable of the same type, but presumably the check wouldn't be required in those cases). So it may as well be forced (when dereferencing and converting to non-nullable), since you'd never really want/need to do otherwise.
>
> Even if the compiler simplified the process by only accepting the exact pattern of "if(x !is null)...", and didn't do any fancier analysis than that, I would still consider that accptable since, as you said, it would be a non-standard use. So therefore, a (very) minor inconvenience like that would be acceptable, particularly considering it would essentially guarantee no null reference errors (aside from manual use of pointers, of course).
The primary use case would be:
nullable T y = something;
non_nullable T x;
if (y) x = non_nullable_cast(y); else return;
This is a problem if T cannot be allocated by default. I have to do something like:
nullable T y = something;
if (!y) return;
auto x = non_nullable_cast(y);
That isn't so bad.
| |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | "Christopher Wright" <dhasenan@gmail.com> wrote in message news:gn3os2$f6j$3@digitalmars.com... > Nick Sabalausky wrote: >> "Brian" <digitalmars@brianguertin.com> wrote in message news:gn3dfn$2lp3$1@digitalmars.com... >>> 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. >> >> I don't see much of a point in not forcing a check. I can't think of a case where it would be useful or desirable to use a nullable type without first checking for null (except for passing it to a func that takes a nullable as a param or assigning it to another nullable of the same type, but presumably the check wouldn't be required in those cases). So it may as well be forced (when dereferencing and converting to non-nullable), since you'd never really want/need to do otherwise. >> >> Even if the compiler simplified the process by only accepting the exact pattern of "if(x !is null)...", and didn't do any fancier analysis than that, I would still consider that accptable since, as you said, it would be a non-standard use. So therefore, a (very) minor inconvenience like that would be acceptable, particularly considering it would essentially guarantee no null reference errors (aside from manual use of pointers, of course). > > The primary use case would be: > nullable T y = something; > non_nullable T x; > if (y) x = non_nullable_cast(y); else return; > > This is a problem if T cannot be allocated by default. I have to do > something like: > nullable T y = something; > if (!y) return; > auto x = non_nullable_cast(y); > > That isn't so bad. I still like this that someone else mentioned: T? x = something; if(x !is null) { // x is implicitly "T" here, not "T?" } else { // handle null condition (x is still "T?") } | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Fri, 13 Feb 2009 21:43:22 +0300, Nick Sabalausky <a@a.a> wrote:
> "Christopher Wright" <dhasenan@gmail.com> wrote in message
> news:gn3os2$f6j$3@digitalmars.com...
>> Nick Sabalausky wrote:
>>> "Brian" <digitalmars@brianguertin.com> wrote in message
>>> news:gn3dfn$2lp3$1@digitalmars.com...
>>>> 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.
>>>
>>> I don't see much of a point in not forcing a check. I can't think of a
>>> case where it would be useful or desirable to use a nullable type without
>>> first checking for null (except for passing it to a func that takes a
>>> nullable as a param or assigning it to another nullable of the same type,
>>> but presumably the check wouldn't be required in those cases). So it may
>>> as well be forced (when dereferencing and converting to non-nullable),
>>> since you'd never really want/need to do otherwise.
>>>
>>> Even if the compiler simplified the process by only accepting the exact
>>> pattern of "if(x !is null)...", and didn't do any fancier analysis than
>>> that, I would still consider that accptable since, as you said, it would
>>> be a non-standard use. So therefore, a (very) minor inconvenience like
>>> that would be acceptable, particularly considering it would essentially
>>> guarantee no null reference errors (aside from manual use of pointers, of
>>> course).
>>
>> The primary use case would be:
>> nullable T y = something;
>> non_nullable T x;
>> if (y) x = non_nullable_cast(y); else return;
>>
>> This is a problem if T cannot be allocated by default. I have to do
>> something like:
>> nullable T y = something;
>> if (!y) return;
>> auto x = non_nullable_cast(y);
>>
>> That isn't so bad.
>
> I still like this that someone else mentioned:
>
> T? x = something;
> if(x !is null)
> {
> // x is implicitly "T" here, not "T?"
> }
> else
> {
> // handle null condition (x is still "T?")
> }
>
>
Or use an existing syntax:
Foo? foo = ...;
if (Foo value = foo) {
// value is a local variable that is only accessible if foo is not null
} else {
// value is not accessible here
}
| |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | "Denis Koroskin" <2korden@gmail.com> wrote in message news:op.upazx0d4o7cclz@proton.creatstudio.intranet... > On Fri, 13 Feb 2009 21:43:22 +0300, Nick Sabalausky <a@a.a> wrote: >> >> I still like this that someone else mentioned: >> >> T? x = something; >> if(x !is null) >> { >> // x is implicitly "T" here, not "T?" >> } >> else >> { >> // handle null condition (x is still "T?") >> } >> >> > > Or use an existing syntax: > > Foo? foo = ...; > if (Foo value = foo) { > // value is a local variable that is only accessible if foo is not > null > } else { > // value is not accessible here > } I could live with that, but I'd prefer my suggestion because it wouldn't require the creation of an extra label for what's essentially the same variable. With your code we'd just end up with a whole bunch of: Foo? myObj = ...; if (Foo nonnullMyObj = myObj) //etc... // or Foo? nullableMyObj = ...; if (Foo myObj = nullableMyObj) //etc... ...Which just seems unnecessary to me. | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:gn4g2n$fbf$1@digitalmars.com... > "Denis Koroskin" <2korden@gmail.com> wrote in message news:op.upazx0d4o7cclz@proton.creatstudio.intranet... >> On Fri, 13 Feb 2009 21:43:22 +0300, Nick Sabalausky <a@a.a> wrote: >>> >>> I still like this that someone else mentioned: >>> >>> T? x = something; >>> if(x !is null) >>> { >>> // x is implicitly "T" here, not "T?" >>> } >>> else >>> { >>> // handle null condition (x is still "T?") >>> } >>> >>> >> >> Or use an existing syntax: >> >> Foo? foo = ...; >> if (Foo value = foo) { >> // value is a local variable that is only accessible if foo is not >> null >> } else { >> // value is not accessible here >> } > > I could live with that, but I'd prefer my suggestion because it wouldn't require the creation of an extra label for what's essentially the same variable. With your code we'd just end up with a whole bunch of: > > Foo? myObj = ...; > if (Foo nonnullMyObj = myObj) //etc... > > // or > > Foo? nullableMyObj = ...; > if (Foo myObj = nullableMyObj) //etc... > > ...Which just seems unnecessary to me. > Another thing to think about is delegates. Even if classes are non-null by default, we can still get the same old null reference problem with delegates: class Foo { void delegate() dg; void callDg() { dg(); // Oops! Forgot to check for null!! } } void main() { auto f = new Foo(); f.callDg(); } This could probably be solved by whatever mechanism is used for classes. | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On Fri, Feb 13, 2009 at 3:23 PM, Nick Sabalausky <a@a.a> wrote:
> Another thing to think about is delegates. Even if classes are non-null by default, we can still get the same old null reference problem with delegates:
>
> class Foo
> {
> void delegate() dg;
> void callDg()
> {
> dg(); // Oops! Forgot to check for null!!
> }
> }
>
> void main()
> {
> auto f = new Foo();
> f.callDg();
> }
>
> This could probably be solved by whatever mechanism is used for classes.
I was thinking nullability would be applicable to all reference types.
A null pointer, delegate, array, or whatever is just as bad as a null
reference.
| |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | On 2009-02-13 14:01:57 -0500, "Nick Sabalausky" <a@a.a> said: >> Or use an existing syntax: >> >> Foo? foo = ...; >> if (Foo value = foo) { >> // value is a local variable that is only accessible if foo is not >> null >> } else { >> // value is not accessible here >> } > > I could live with that, but I'd prefer my suggestion because it wouldn't > require the creation of an extra label for what's essentially the same > variable. With your code we'd just end up with a whole bunch of: > > Foo? myObj = ...; > if (Foo nonnullMyObj = myObj) //etc... > > // or > > Foo? nullableMyObj = ...; > if (Foo myObj = nullableMyObj) //etc... > > ...Which just seems unnecessary to me. The problem with retyping the same variable is that it may gives strange situations. For instance, is this an error? Foo? myObj = ...; if (myObj !is null) { doSomethingWith(myObj); myObj = null; // should this be an error? } And what about: Foo? myObj = ...; while (myObj !is null) myObj = myObj.next; If you want to avoid verbosity, you'll need to retype the variable until it gets assigned another potentially non-null value. Basically, you'll need to perform flow analysis inside the function to enforce that. -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | On 2009-02-13 16:30:59 -0500, Jarrett Billingsley <jarrett.billingsley@gmail.com> said: > I was thinking nullability would be applicable to all reference types. > A null pointer, delegate, array, or whatever is just as bad as a null > reference. That's right with me, except for arrays for which there is bound checking safeties in place. A null array and an empty array should be undistinguishable in my opinion. -- Michel Fortin michel.fortin@michelf.com http://michelf.com/ | |||
February 13, 2009 Re: (non)nullable types | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin |
Denis Koroskin wrote:
> [snip]
>>
>> I still like this that someone else mentioned:
>>
>> T? x = something;
>> if(x !is null)
>> {
>> // x is implicitly "T" here, not "T?"
>> }
>> else
>> {
>> // handle null condition (x is still "T?")
>> }
>>
>>
>
> Or use an existing syntax:
>
> Foo? foo = ...;
> if (Foo value = foo) {
> // value is a local variable that is only accessible if foo is not null
> } else {
> // value is not accessible here
> }
Both of these syntaxes are solving a problem that doesn't exist. This is why we have null dereference exceptions: accessing a null pointer is an error. All this is doing is moving the onus for the check from the hardware to the programmer.
Leave magic out of the language and let the hardware do it's job. If you have a nullable type, it's because you WANT it to be nullable, and you shouldn't have to stand on one leg and jump through a burning hoop every time you want to look at the damn thing.
The point here is not to make using null harder, it's to make not using null easier.
-- Daniel
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply