April 21, 2012
On Saturday, 21 April 2012 at 23:27:38 UTC, Namespace wrote:
> But one thing: i missed there an invariant which check if t is null.
> If i write "f.t = null;" no error occured.

Don't do that!

Maybe I should make t private...

April 21, 2012
On Saturday, 21 April 2012 at 23:26:04 UTC, bearophile wrote:
> I think before putting something in Phobos it's generally better to have used it in Real Code for some time.

I agree, but this comes up a LOT on the newsgroup,
so I figure we need to get something up there to point
people to.

> I am not sure a mostly-library-defined solution (mostly because @disable is a built-in)

lol, all library implementations use language features!

> I will try to use your NotNull struct.

Thanks! Let you know what you think of it. I'm sure
we can do a good job with this.
April 22, 2012
I just pushed an update to git with
a few changes people have suggested.

I removed one of the old opAssigns
to keep a static type check.

Added assumeNotNull and checkNotNull
as entry points.

Made the data member private.


I think that's closer to what everyone
wants.
April 22, 2012
On Sunday, 22 April 2012 at 00:06:47 UTC, Adam D. Ruppe wrote:
> I just pushed an update to git with
> a few changes people have suggested.
>
> I removed one of the old opAssigns
> to keep a static type check.
>
> Added assumeNotNull and checkNotNull
> as entry points.
>
> Made the data member private.
>
>
> I think that's closer to what everyone
> wants.

Great work, but strange that the invariant break the whole code.

Has anyone here an idea, how a implicit cast can work?
Something like that should work:

void foo(Foo f) { }
void bar(NotNull!(Foo) f) { }

Foo f = new Foo();

foo(f);
bar(f);

At the moment you must do it with

bar(assumeNotNull(f));

and so you have twice as much work as actually being necessary. So in my opinion it must exist a way to avoid a explicit "cast" with assumeNotNull(f) on the caller side. Otherwise a check with assert(obj !is null); before you pass it to the method and then in the method again would do the same, and it's the same overhead.
I think without the possibility to "cast" Foo without any explicit function call to NotNull!(Foo), there are not much advantages.

What do you say?

April 22, 2012
On Sunday, 22 April 2012 at 00:06:47 UTC, Adam D. Ruppe wrote:
> Made the data member private.

But if the struct is in a separate module you get an error.
So you must write

T get() {
	return this._notNullData;
}
	
alias get this;

instead

alias _notNullData this; /// this is substitutable for the regular (nullable) type

April 22, 2012
On Sunday, 22 April 2012 at 00:06:47 UTC, Adam D. Ruppe wrote:
> I just pushed an update to git with
> a few changes people have suggested.
>
> I removed one of the old opAssigns
> to keep a static type check.
>
> Added assumeNotNull and checkNotNull
> as entry points.

I didn't recognized this part until now.

The opAssign is still there and that's good.
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?
If so, that would increase the annoying factor which is still there because of the explicit conversion constraint from Foo into NotNull!(Foo) which i described in my post above.
April 22, 2012
On Saturday, 21 April 2012 at 22:18:02 UTC, Adam D. Ruppe wrote:
> We can do not null in the library reasonably
> well. I have a basic one in github:
>
> https://github.com/D-Programming-Language/phobos/pull/477

I'm thinking those interested in not null will want something similar to the maybe type. 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)?

import std.stdio;

void main() {
    int* a;
    int i = 5;

    checkNull!(
              t => safe(t),
              () { unsafe(a); })
        (a);

    a = &i;

    checkNull!(
               t => safe(t))
        (a);

}

void checkNull(alias nn, alias n = () {}, T)(T a) {
    if(a !is null)
        nn(assumeNotNull(a));
    else
        n();
}


void safe(NotNull!(int*) i) {
    writeln(*i);
}

void unsafe(int* i) {
    writeln(i);
}

April 23, 2012
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?
April 23, 2012
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.
April 23, 2012
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.

-- 
Dmitry Olshansky
1 2 3 4
Top | Discussion index | About this forum | D home