April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Mon, 23 Apr 2012 10:38:27 +0200, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
> On 23.04.2012 12:06, Simen Kjaeraas wrote:
>> On Mon, 23 Apr 2012 09:14:12 +0200, Namespace <rswhite4@googlemail.com>
>> wrote:
>>
>>> I made several tests with NotNull yesterday and actually they all passed.
>>> In special cases i didn't get a compiler error but then a runtime
>>> error is better then nothing. :)
>>>
>>> But there is still my problem with this:
>>>
>>> void foo(NotNull!(Foo) n) {
>>>
>>> }
>>>
>>> void bar(Foo n) {
>>>
>>> }
>>>
>>> in my optinion it must exist a way that both
>>> NotNull!(Foo) nf = new Foo();
>>>
>>> foo(nf);
>>> bar(nf);
>>>
>>> and furhtermore
>>> Foo f = new Foo();
>>>
>>> foo(f);
>>> bar(f);
>>>
>>> compiles.
>>> We need some hack, implicit cast or compiler cast that cast or passes
>>> Foo to NotNull!(Foo).
>>>
>>> Any suggestions?
>>
>> No. The whole point of NotNull is that it should enforce not being null.
>> Allowing implicit casting from PossiblyNull to NotNull would break this.
>
> Just include obligatory run-time check when crossing null-NotNull boundaries.
>
Which carries with it hidden runtime costs that are unacceptable to some.
The point of NotNull is twofold - safety (you know it's not null) and speed
(you don't need to check if it's null). The latter goes out the window if
implicit casting were allowed.
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | > No. The whole point of NotNull is that it should enforce not being null.
> Allowing implicit casting from PossiblyNull to NotNull would break this.
Then i'm further for a keyword that checks an object for not null.
Or you check at runtime to avoid null, e.g. with assert or enforce.
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Monday, 23 April 2012 at 08:47:22 UTC, Simen Kjaeraas wrote:
> On Mon, 23 Apr 2012 10:38:27 +0200, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>
>> On 23.04.2012 12:06, Simen Kjaeraas wrote:
>>> On Mon, 23 Apr 2012 09:14:12 +0200, Namespace <rswhite4@googlemail.com>
>>> wrote:
>>>
>>>> I made several tests with NotNull yesterday and actually they all passed.
>>>> In special cases i didn't get a compiler error but then a runtime
>>>> error is better then nothing. :)
>>>>
>>>> But there is still my problem with this:
>>>>
>>>> void foo(NotNull!(Foo) n) {
>>>>
>>>> }
>>>>
>>>> void bar(Foo n) {
>>>>
>>>> }
>>>>
>>>> in my optinion it must exist a way that both
>>>> NotNull!(Foo) nf = new Foo();
>>>>
>>>> foo(nf);
>>>> bar(nf);
>>>>
>>>> and furhtermore
>>>> Foo f = new Foo();
>>>>
>>>> foo(f);
>>>> bar(f);
>>>>
>>>> compiles.
>>>> We need some hack, implicit cast or compiler cast that cast or passes
>>>> Foo to NotNull!(Foo).
>>>>
>>>> Any suggestions?
>>>
>>> No. The whole point of NotNull is that it should enforce not being null.
>>> Allowing implicit casting from PossiblyNull to NotNull would break this.
>>
>> Just include obligatory run-time check when crossing null-NotNull boundaries.
>>
>
> Which carries with it hidden runtime costs that are unacceptable to some.
> The point of NotNull is twofold - safety (you know it's not null) and speed
> (you don't need to check if it's null). The latter goes out the window if
> implicit casting were allowed.
Allow both: a type for explicit not null which cannot be changed to null and a keyword or some other construct which can check any possible object at compile time if it's null.
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | Am 23.04.2012 09:14, schrieb Namespace:
> I made several tests with NotNull yesterday and actually they all passed.
> In special cases i didn't get a compiler error but then a runtime error
> is better then nothing. :)
>
> But there is still my problem with this:
>
> void foo(NotNull!(Foo) n) {
>
> }
>
> void bar(Foo n) {
>
> }
>
> in my optinion it must exist a way that both
> NotNull!(Foo) nf = new Foo();
>
> foo(nf);
> bar(nf);
>
> and furhtermore
> Foo f = new Foo();
>
> foo(f);
> bar(f);
>
> compiles.
> We need some hack, implicit cast or compiler cast that cast or passes
> Foo to NotNull!(Foo).
>
> Any suggestions?
If you replace
alias _notNullData this;
with
@property T _notNullDataHelper()
{
assert(_notNullData !is null);
return _notNullData;
}
alias _notNullDataHelper this;
It will not be possible to assign to _notNullData
It will still be possbile to use from other modules
NotNull!T will implicitly convert to T (your first case)
However T will not implicitly convert to NotNull!T (as far as I know such a implict conversion is not possible in D, i suggested a @implicit modifier for a constructor to allow such implicit type conversions, but it was rejected)
Kind Regards
Benjamin Thaut
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Sunday, 22 April 2012 at 16:59:05 UTC, Jesse Phillips wrote:
> As such checkNotNull shoud be more than throwing an exception. I have tried this, but it should get some constraints. Also wouldn't the new lambda syntax look nice with null here: null => unsafe(a)?
Yeah, I like this idea, though a lot of what I do
is more like
if(x !is null) use(x);
hmmmm, the default could be to simply do nothing on
the other side. I think we can work with the lambda idea.
The other null related things on my mind are:
1) if we could make new return NotNull!T. I guess
we could offer an alternative:
NotNull!T create(T, Args...)(Args) {
return assumeNotNull(new T(Args));
}
Though "new" is so well entrenched that I don't think
it is going anywhere, and having a language construct
depend on a library structure is pretty meh.
So meh.
2) When doing chained calls, have it simply ignore the
rest when it hits null.
suppose:
if(a) if(auto b = a.something) b.more();
I guess some languages would call that
a?.something?.more();
but I wonder if we can do it in a library somehow.
ifNotNull(a).something.more();
Suppose it returns a wrapper of a that has an opDispatch
or something that includes the if check, and wraps
the rest of the return values.
I'm pretty sure we can do that!
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Sunday, 22 April 2012 at 10:58:10 UTC, Namespace wrote: > If i got you right on git, you wouldn't allow something like this: > NotNull!(Foo) f = new Foo(); and instead you want that everybody writes > NotNull!(Foo) f = assumeNotNull(new Foo); > Is that correct? No, I think that's too annoying, though I also think it is more correct. But my plan is to allow NotNull!Foo f = new Foo(). (This is a constructor, so removing opAssign doesn't change this.) > there because of the explicit conversion constraint from Foo into NotNull!(Foo) which i described in my post above. That explicit conversion is one of the features of the type - it means the compiler will remind you when you missed something. There's really little benefit to checking at a function automatically. If you need that, you can always assert for it in an in{} contract. Or just use it and let the debugger take care of the rest. I think a debug build on Windows even gives a stack trace on null deref, but I'm not sure. The big benefit with not null types is making sure you don't store a null somewhere, since that's a lot harder to track down. |
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On Monday, 23 April 2012 at 11:04:24 UTC, Benjamin Thaut wrote: > Am 23.04.2012 09:14, schrieb Namespace: >> I made several tests with NotNull yesterday and actually they all passed. >> In special cases i didn't get a compiler error but then a runtime error >> is better then nothing. :) >> >> But there is still my problem with this: >> >> void foo(NotNull!(Foo) n) { >> >> } >> >> void bar(Foo n) { >> >> } >> >> in my optinion it must exist a way that both >> NotNull!(Foo) nf = new Foo(); >> >> foo(nf); >> bar(nf); >> >> and furhtermore >> Foo f = new Foo(); >> >> foo(f); >> bar(f); >> >> compiles. >> We need some hack, implicit cast or compiler cast that cast or passes >> Foo to NotNull!(Foo). >> >> Any suggestions? > > If you replace > > alias _notNullData this; > > with > > @property T _notNullDataHelper() > { > assert(_notNullData !is null); > return _notNullData; > } > > alias _notNullDataHelper this; > > It will not be possible to assign to _notNullData > It will still be possbile to use from other modules Yes, that's what i wrote a site before. Otherwise you couldn't use it in other modules, that's right. > NotNull!T will implicitly convert to T (your first case) > However T will not implicitly convert to NotNull!T (as far as I know such a implict conversion is not possible in D, i suggested a @implicit modifier for a constructor to allow such implicit type conversions, but it was rejected) > > Kind Regards > Benjamin Thaut That is bad. Without the possibility of such implicit constructs NotNull isn't usefull at all. I wouldn't write for all the objects which i would check "method_with_not_null_object(ConvertToNotNull(f_obj));" That isn't helpfull, that makes more work as a sugesstion in the method with assert(obj !is null); and that was what i wanted avoid. Why this reluctance against a keyword to check a normal Object which is passed as parameter, e.g. @notNull Foo f? I didn't understood it. Please explain that to me. My previous language was C++ and so my first thoughts were that only pointer types can be null but not references. And then i've learned that D allows this behavoiur for both: refernces e.g. objects that passes as parameter and even for pointer types. That's a point which i will never understand. |
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Monday, 23 April 2012 at 14:31:05 UTC, Namespace wrote: > Yes, that's what i wrote a site before. Otherwise you couldn't > use it in other modules, that's right. yeah i'll fix that next time i work on it. > I wouldn't write for all the objects which i would check > "method_with_not_null_object(ConvertToNotNull(f_obj));" The idea is to use NotNull!T to store your stuff, so there's no need to convert. > Why this reluctance against a keyword to check a normal Object > which is passed as parameter, e.g. @notNull Foo f? Because the hardware already does that, for the most part. That's what "access violation" means. The hard part is figuring out /why/ it is null, and the not null type helps that by catching it when you store it instead of when you use it. |
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Monday, 23 April 2012 at 14:50:14 UTC, Adam D. Ruppe wrote:
> On Monday, 23 April 2012 at 14:31:05 UTC, Namespace wrote:
>> Yes, that's what i wrote a site before. Otherwise you couldn't
>> use it in other modules, that's right.
>
> yeah i'll fix that next time i work on it.
>
>> I wouldn't write for all the objects which i would check
>> "method_with_not_null_object(ConvertToNotNull(f_obj));"
>
> The idea is to use NotNull!T to store your stuff,
> so there's no need to convert.
>
>> Why this reluctance against a keyword to check a normal Object
>> which is passed as parameter, e.g. @notNull Foo f?
>
> Because the hardware already does that, for the most part.
> That's what "access violation" means.
>
> The hard part is figuring out /why/ it is null, and the
> not null type helps that by catching it when you store
> it instead of when you use it.
So if i wouldn't want such annoying debugging for a simple error (which gave me no further information), i must catch this stupid access violation by myself with assert/enforce or i use for all relevant objects NotNull? That is very inconvenient...
And all that because NullPointer Exceptions or checks to assume not null (even with a explicit keyword!) would decrease the speed?
|
April 23, 2012 Re: Keyword to avoid not null references | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | I thought that something like this // not_null_struct.d NotNull!(T) assumeNotNull(T : Object)(T t) { return NotNull!(T)(t); } @property NotNull!(T) makeNotNull(T : Object)() { T t = new T(); return assumeNotNull(t); } // not_null.d which import not_null_struct.d NotNull!(Foo) _convert() { //return NotNull!(Foo)(this); // prints: Stack overflow return assumeNotNull(this); } alias _convert this; would allow me to convert Foo to NotNull!(Foo) implicit. But it doesn't work. I get this error: not_null.d(37): Error: template instance not_null_struct.assumeNotNull!(Foo) recursive expansion Line 37 is the return in the _convert method. Does anybody know why? I thought that would a smart idea... |
Copyright © 1999-2021 by the D Language Foundation