www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Keyword to avoid not null references

reply "Namespace" <rswhite4 googlemail.com> writes:
My question is, why D hasn't got an explicit Keyword to check at 
compile time for non null references?
I understand that such check when they're implicit and refer to 
all objects they slow down the programm, but why doesn't exist an 
explicit keyword like  ref or a simple ' ' before the Object name 
or value.
Right now it's very annoying because i get a cryptical error 
message "Access violation" without any further informations and I 
have to debug. Only that way I can find where the Null references 
would access and then, why _and_ where the null references came 
from. That sucks.
I hate it and so i write in every method to avoid null references 
"assert(obj !is null);". Now i get an assertion if obj is null 
and also the file and line. 50% less work then before.
But it's still a runtime error and explicit work which can easily 
be checked by the compiler at compile time. Then i know: "oh 
there are null references and there shouldn't be any". So what 
are the reasons against a special keyword to let the compiler 
check for non references? I didn't understood it. I heard similar 

did implement something for that?

Some variants I have already seen: const Foo  obj, const  Foo obj 
or my favourite: const  ref Foo obj.

Greetz
Apr 21 2012
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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
Apr 21 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
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
So every time i want to avoid null references i have to write "NotNull!(Foo) f" (or better, because it's a struct: "ref NotNull!(Foo) f")? And therefore i must initialize them with NotNull!(Foo) f = new Foo();? That would be a little annoying. What if i needed in function bar only Foo f which can be null but in quatz i need a not null Reference? In my opinion the best way would be to initialize them with Foo f = new Foo(); and if i pass them to bar, it will be implicit cast to NotNull!(Foo). I think, that would be the best idea. The only thing that disturbing me, is, that it is a struct and therefore it passes by value instead as reference and that it is more to write as just " " or " ref".
Apr 21 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/22/2012 12:48 AM, Namespace wrote:
 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
So every time i want to avoid null references i have to write "NotNull!(Foo) f" (or better, because it's a struct: "ref NotNull!(Foo) f")? And therefore i must initialize them with NotNull!(Foo) f = new Foo();? That would be a little annoying. What if i needed in function bar only Foo f which can be null but in quatz i need a not null Reference? In my opinion the best way would be to initialize them with Foo f = new Foo(); and if i pass them to bar, it will be implicit cast to NotNull!(Foo).
But this implies a runtime check.
 I think, that would be the best idea.
 The only thing that disturbing me, is, that it is a struct and therefore
 it passes by value instead as reference
You might have a wrong mental model of how classes and structs work in D. A class reference is much like a struct of the following form: struct ClassRef{ ClassImpl* impl; }
 and that it is more to write as
 just " " or " ref".
And only the trivial cases are catched during compilation.
Apr 21 2012
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 21 April 2012 at 22:48:27 UTC, Namespace wrote:
 So every time i want to avoid null references i have to write 
 "NotNull!(Foo) f" (or better, because it's a struct: "ref 
 NotNull!(Foo) f")?
It is already a reference! Otherwise, it couldn't be null anyway. But, yes, you'd write NotNull!Foo. If "NotNull" is too long for you, you could always alias it to something else. alias NotNull n; n!Foo f; whatever floats your boat.
 And therefore i must initialize them with NotNull!(Foo) f = new 
 Foo();? That would be a little annoying.
If you don't initialize it, it would be null... so yes, you have to initialize it.
 What if i needed in function bar only Foo f which can be null 
 but in quatz i need a not null Reference?
If it can be null, you check for null or assume it isn't and just pass it straight to NotNull. One of the pull request comments suggests adding assumeNotNull and checkNotNull to help with this. I'll add that later.
 In my opinion the best way would be to initialize them with Foo 
 f = new Foo(); and if i pass them to bar, it will be implicit 
 cast to NotNull!(Foo).
An implicit cast to not null would defeat the point of the new type! It implicitly casts to the regular (nullable) type, but going from null to not null implicitly means you have no help in catching it from the type system.
Apr 21 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
I see you're right. Great! But it is only on git hub and not in 
the standard typecons header in 2.059, right?
Apr 21 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Saturday, 21 April 2012 at 23:18:40 UTC, Namespace wrote:
 I see you're right. Great! But it is only on git hub and not in 
 the standard typecons header in 2.059, right?
But one thing: i missed there an invariant which check if t is null. If i write "f.t = null;" no error occured.
Apr 21 2012
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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...
Apr 21 2012
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Apr 21 2012
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
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?
Apr 22 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
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
Apr 22 2012
prev sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
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.
Apr 22 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
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?
Apr 23 2012
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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.
Apr 23 2012
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
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
Apr 23 2012
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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.
Apr 23 2012
parent "Namespace" <rswhite4 googlemail.com> writes:
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.
Apr 23 2012
prev sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 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.
Apr 23 2012
prev sibling parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
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
Apr 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
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.
Apr 23 2012
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Apr 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
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?
Apr 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
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...
Apr 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Monday, 23 April 2012 at 17:18:30 UTC, Namespace wrote:
 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...
I see, if i comment out "alias _get this;" in NotNull it works fine and i can implicit convert Foo to NotNull!(Foo). But why doesn't it work shareable? In that case it would be nearly perfect for me. Does anyone know how it could work? In my opinion both variants have to work shareable. Don't they?
Apr 23 2012
parent "Namespace" <rswhite4 googlemail.com> writes:
After i'm sure, that this is a bug: Great work again.
If this bug will be fixed soon or someone can help me to find a 
workaround, then NotNull would be exactly what I always wanted.
Apr 24 2012
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Apr 23 2012
prev sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 21 April 2012 at 23:18:40 UTC, Namespace wrote:
 I see you're right. Great! But it is only on git hub and not in 
 the standard typecons header in 2.059, right?
Right, I missed the deadline for that.
Apr 21 2012
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:
 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
It says:
I haven't actually used any NotNull in practice, but from the 
attached tests, it looks like it will work well - hence, the 
pull request.<
I think before putting something in Phobos it's generally better to have used it in Real Code for some time. I am not sure a mostly-library-defined solution (mostly because disable is a built-in) is good enough compared to a solution built in the type system. I will try to use your NotNull struct. Bye, bearophile
Apr 21 2012
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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.
Apr 21 2012
prev sibling parent reply "Jesse Phillips" <jessekphillips+D gmail.com> writes:
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); }
Apr 22 2012
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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!
Apr 23 2012
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/21/2012 11:40 PM, Namespace wrote:
 My question is, why D hasn't got an explicit Keyword to check at compile
 time for non null references?
It shouldn't be a special keyword. If the compiler can do the necessary analysis to actually enforce that the reference cannot hold a null reference, then it should be the default. Most references are not null.
 I understand that such check when they're implicit and refer to all
 objects they slow down the programm,
How would such a check slow down the program? The rest of your post seems to indicate that you want a compile time check.
 but why doesn't exist an explicit
 keyword like  ref or a simple ' ' before the Object name or value.
 Right now it's very annoying because i get a cryptical error message
 "Access violation" without any further informations and I have to debug.
 Only that way I can find where the Null references would access and
 then, why _and_ where the null references came from. That sucks.
 I hate it and so i write in every method to avoid null references
 "assert(obj !is null);". Now i get an assertion if obj is null and also
 the file and line. 50% less work then before.
 But it's still a runtime error and explicit work which can easily be
 checked by the compiler at compile time.
'Easily' would be an oversimplification. There are distinct issues to be solved by the type system, mostly surrounding initialisation.
 Then i know: "oh there are null
 references and there shouldn't be any". So what are the reasons against
 a special keyword to let the compiler check for non references?
There are seldom reasons _against_ a language feature. To make it in, there must be reasons to adapt it. And even more importantly, there must be a good design that integrates well with the rest of the language. Having a non-null type system would certainly be desirable, but it would be a breaking language change if it was actually designed to be useful.

In what way would that be a regression?
 so why didn't D made it better and did implement something for that?

 Some variants I have already seen: const Foo  obj, const  Foo obj or my
 favourite: const  ref Foo obj.

 Greetz
Well, that is the grammar of the feature, but you have not described how it should work. (Saying that the compiler should emit an error for null references does not cut it.)
Apr 21 2012