Re: References in D

2012-10-07 Thread David Piepgrass

void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from?  Not a. Not p; the while 
loop happened to be never executed.  To say b would be 
closer, but still imprecise.  Actually it was created in the 
q() function that was called by u() that was called by b() 
which then created a class that held the null value and was 
passed to a() that then dereferenced the class and returned the 
value stored in the class that happened to be null.  nulls 
create very non-local bugs, and that's why they frustrate me to 
no end sometimes.


Since this thread's attracted lots of commotion I thought I'd 
just drop by and +1 for non-nullable types, and +1 for your 
arguments.


I keep wondering, though, if it is 'enough' to solve the null 
problem, or if it would be possible to devise a more general 
mechanism for solving other problems too, like say, the fact that 
certain integers have to always be positive, or if you want to go 
more general, that a certain relationship must hold between two 
structures...


Not having used D's invariants so far (well, I haven't used D 
itself for a real project actually)... what's stopping D's 
invariant mechanism from handling all this?


http://dlang.org/class.html#invariants (as is typical of D 
documentation, this says nothing about invariants on structs, but 
the page about structs says that they support invariants with an 
X.)


I mean, problems are detected at runtime this way, and slightly 
too late, but still, it would be better than most popular 
languages that can't do anything about nulls at all. Since D's 
devs don't even seem to have enough time to implement D as 
described in TDPL (published more than two years ago), I wouldn't 
expect to see this feature in the D language in the near future.


Re: References in D

2012-10-07 Thread Chad J

On 10/07/2012 02:22 AM, David Piepgrass wrote:

void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from? Not a. Not p; the while loop
happened to be never executed. To say b would be closer, but still
imprecise. Actually it was created in the q() function that was called
by u() that was called by b() which then created a class that held the
null value and was passed to a() that then dereferenced the class and
returned the value stored in the class that happened to be null. nulls
create very non-local bugs, and that's why they frustrate me to no end
sometimes.


Since this thread's attracted lots of commotion I thought I'd just drop
by and +1 for non-nullable types, and +1 for your arguments.

I keep wondering, though, if it is 'enough' to solve the null problem,
or if it would be possible to devise a more general mechanism for
solving other problems too, like say, the fact that certain integers
have to always be positive, or if you want to go more general, that a
certain relationship must hold between two structures...



I agree.


Not having used D's invariants so far (well, I haven't used D itself for
a real project actually)... what's stopping D's invariant mechanism from
handling all this?

http://dlang.org/class.html#invariants (as is typical of D
documentation, this says nothing about invariants on structs, but the
page about structs says that they support invariants with an X.)

I mean, problems are detected at runtime this way, and slightly too
late, but still, it would be better than most popular languages that
can't do anything about nulls at all. Since D's devs don't even seem to
have enough time to implement D as described in TDPL (published more
than two years ago), I wouldn't expect to see this feature in the D
language in the near future.


Invariants might work... create a proxy struct and then have assignment 
always check the invariant.  I don't like the idea that they get removed 
during release mode.  I'd like to be able to control which checks I pay 
for.  I think this might just mean that the important thing is 
overloading assignment to do checks, which could be done in principle, 
and this could work without invariants and thus give the desired control.


I just haven't had much luck creating proxy types in the past.  As of 
some months ago, D just wasn't there yet.  :(


In another post in this thread I mentioned something similar:



It would be cool to have templates like this:

51.  bool isPrime(int val)
52.  {
53.  ...
54.  }

101. Watch!(int,isPrime) primeNumber = primeGenerator();
102. primeNumber = 8;
103. doStuff();
104. checkPrime(primeNumber); /+ Crash! +/
Error: checkPrime(primeNumber): primeNumber is not prime.
primeNumber: isPrime returned false after assignment at
  (foobar.d, line 102)

~or~

101. Constrain!(int,isPrime) primeNumber = primeGenerator();
102. primeNumber = 8; /+ Crash! +/
103. doStuff();
104. checkPrime(primeNumber);
foobar.d, line 102: isPrime returned false after assignment.

For convenience one could define this:
alias Constrain!(int,isPrime) PrimeInt;


Maybe these could be turned on/off in release mode on a case-by-case 
basis.  I would probably leave the checks and tracking in always, with 
the one exception of code that has been shown (with profiling) to need 
the extra performance.




Re: References in D

2012-10-06 Thread Franciszek Czekała

On Saturday, 6 October 2012 at 04:10:28 UTC, Chad J wrote:

On 10/05/2012 08:31 AM, Regan Heath wrote:

On Fri, 05 Oct 2012 05:19:13 +0100, Alex Burton
alexibureplacewithz...@gmail.com wrote:

On Saturday, 15 September 2012 at 17:51:39 UTC, Jonathan M 
Davis wrote:
On Saturday, September 15, 2012 19:35:44 Alex Rønne 
Petersen wrote:
Out of curiosity: Why? How often does your code actually 
accept null as

a valid state of a class reference?


I have no idea. I know that it's a non-negligible amount of 
the time,

though
it's certainly true that they normally have values. But null 
is how you
indicate that a reference has no value. The same goes for 
arrays and

pointers.
Sometimes it's useful to have null and sometimes it's useful 
to know

that a
value can't be null. I confess though that I find it very 
surprising

how much
some people push for non-nullable references, since I've 
never really

found
null to be a problem. Sure, once in a while, you get a null
pointer/reference
and something blows up, but that's very rare in my 
experience, so I

can't help
but think that people who hit issues with null pointers on a 
regular

basis are
doing something wrong.

- Jonathan M Davis


In my experience this sort of attutide is not workable in 
projects

with more than one developer.


Almost all my work is on projects with multiple developers in 
C/C++ and

making extensive use of null.

It all works OK if everyone knows the 'rules' about when to 
check for

null and when not to.


As every good C/C++ developer does. The rule is simple, always 
check for
nulls on input passed to public functions/methods. What you 
do with
internal protected and private functions and methods is up to 
you (I use

assert).

Telling team members that find bugs caused by your null 
references
that they are doing it wrong and next time should check for 
null is a

poor substitute for having the language define the rules.


Having language defined rules is a nice added /bonus/ it 
doesn't let you

off the hook when it comes to being null safe in your code.

A defensive attitude of checking for null everywhere like I 
have seen

in many C++ projects makes the code ugly.


That's a matter of opinion. I like to see null checks at the 
top of a
function or method, it makes it far more likely to be safe and 
it means
I can ignore the possibility of null from then on - making the 
code much

cleaner.

R



I find this to be very suboptimal at the least.

This prevents null values from traveling up the stack, but 
still allows them to move down (as return values) and allows 
them to survive multiple unrelated function calls.


It catches null values once they've already ended up in a place 
they shouldn't be.  Too late.


Nulls can also be placed into variables within structs or 
classes that then get passed around.  Checking for those can 
require some complex traversal: impractical for casual one-off 
checks at the start of a function in some cases.


void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from?  Not a. Not p; the while 
loop happened to be never executed.  To say b would be 
closer, but still imprecise.  Actually it was created in the 
q() function that was called by u() that was called by b() 
which then created a class that held the null value and was 
passed to a() that then dereferenced the class and returned the 
value stored in the class that happened to be null.  nulls 
create very non-local bugs, and that's why they frustrate me to 
no end sometimes.


What I really want to know is where errant null values come 
FROM.


I also want to know this /at compile time/, because debugging 
run-time errors is time consuming and debugging compile-time 
errors is not.


The above example could yield the unchecked null assignment at 
compile time if all of the types involved were typed as 
non-nullable, except for the very bare minimum that needs to be 
nullable.  If something is explicitly nullable, then its 
enclosing function/class is responsible for handling null 
conditions before passing it into non-nullable space.
 If a function/class with nullable state tries to pass a null 
value into non-nullable space, then it is a bug.  This contains 
the non-locality of null values as much as is reasonably 
possible.


Additionally, it might be nice to have a runtime nullable type 
that uses its object file's debugging information to remember 
which file/function/line that its null value originated from 
(if it happens to be null at all).  This would make for some 
even better diagnostics when code that HAS to deal with null 
values eventually breaks and needs to dump a stack trace on 
some poor unsuspecting sap (that isn't me) or ideally sends an 
email to the responsible staff (which is me).



returned the value stored in the class that happened to be null.



Re: References in D

2012-10-06 Thread bearophile

Franciszek Czekała:

Insistance on formal tools is a misunderstanding that leads to 
design bloat and eventually failure (Ada).


D competes directly with C++ as Ada did before. Ada drowned 
under the weight of its safety and so will D if it goes the 
same route. The only thing needed now are mature compilers and 
good systems API integration. If anything I would rather 
consider removing features from the language than adding them.


Ada has not failed, it's a niche language, but at the moment in 
its niche (high integrity code) it's used and I think there its 
usage is growing. (And Ada is used far more than D, there are 
many important system that use Ada, unlike D).


I think the usage of formal tools is slowly growing (despite 
being tiny).


Probably Ada has failed to become more widespread mostly because 
its syntax requires to write too much code and to state too many 
things two times. And because it's Pascal-like. And maybe a bit 
because of its military origins too.


And while Ada/Spark are safe, there are more modern ways to 
obtain some safety that require to write less code. You see this 
a little even in Rust.


D is not half as safe as Ada, D is C-derived, D syntax allows to 
write code quite more succinct than C# code. So comparing Ada and 
D, despite D likes some extra safety compared to C++, is not so 
meaningful.


Bye,
bearophile


Re: References in D

2012-10-06 Thread Timon Gehr

On 10/06/2012 10:18 AM, Franciszek Czekała h...@valentimex.com wrote:

Every function should define its interface, its contract
with the outside world. If a() function returns a pointer it is a part
of the contract whether it can be null.


The default should be it can't be null. Why would it be null?


Two possibilities:

A) The contract says it can be null. Then it is your duty to check for
null. Period. Learn to read the signs before you start driving. You
assinged the value without checking, it is your fault, not a()'s, not
the language's.



It does not matter whose fault it is. The tree/car/software is broken
already. Google 'automatic braking system'.


B) The description of a() says the return value cannot be null. Then a()
should check its return value before returning or make otherwise sure it
is not null. If it returns null it is a bug. One of the infinite number
of possible bugs that can happen. Again it is not the problem of the
language. The problem of divergence of specification and code is a human
problem that cannot be solved formally.


If the contract does not have to talk about null values when they are
unimportant, the problem does not even occur.


Re: References in D

2012-10-06 Thread Chad J

On 10/06/2012 04:18 AM, Franciszek Czekała h...@valentimex.com wrote:

On Saturday, 6 October 2012 at 04:10:28 UTC, Chad J wrote:


I find this to be very suboptimal at the least.

This prevents null values from traveling up the stack, but still
allows them to move down (as return values) and allows them to
survive multiple unrelated function calls.

It catches null values once they've already ended up in a place they
shouldn't be. Too late.

Nulls can also be placed into variables within structs or classes that
then get passed around. Checking for those can require some complex
traversal: impractical for casual one-off checks at the start of a
function in some cases.

void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from? Not a. Not p; the while loop
happened to be never executed. To say b would be closer, but still
imprecise. Actually it was created in the q() function that was called
by u() that was called by b() which then created a class that held the
null value and was passed to a() that then dereferenced the class and
returned the value stored in the class that happened to be null. nulls
create very non-local bugs, and that's why they frustrate me to no end
sometimes.

What I really want to know is where errant null values come FROM.

I also want to know this /at compile time/, because debugging run-time
errors is time consuming and debugging compile-time errors is not.

The above example could yield the unchecked null assignment at compile
time if all of the types involved were typed as non-nullable, except
for the very bare minimum that needs to be nullable. If something is
explicitly nullable, then its enclosing function/class is responsible
for handling null conditions before passing it into non-nullable space.
If a function/class with nullable state tries to pass a null value
into non-nullable space, then it is a bug. This contains the
non-locality of null values as much as is reasonably possible.

Additionally, it might be nice to have a runtime nullable type that
uses its object file's debugging information to remember which
file/function/line that its null value originated from (if it happens
to be null at all). This would make for some even better diagnostics
when code that HAS to deal with null values eventually breaks and
needs to dump a stack trace on some poor unsuspecting sap (that isn't
me) or ideally sends an email to the responsible staff (which is me).



returned the value stored in the class that happened to be null.


Happened? I was driving carefully and then it happened I drove into the
tree, officer. Every function should define its interface, its contract
with the outside world. If a() function returns a pointer it is a part
of the contract whether it can be null. Two possibilities:

A) The contract says it can be null. Then it is your duty to check for
null. Period. Learn to read the signs before you start driving. You
assinged the value without checking, it is your fault, not a()'s, not
the language's.



I am unconvinced by the driving analogy.  When driving, most of the 
important bits become muscle memory (acceleration, braking, turn 
signals, etc) and the rest falls under the category of be aware.  The 
factor in our advantage is that awareness in driving usually only 
requires you to focus on one thing at a time: turn your head before 
changing lanes or turning, look at the sides of the road, check your 
rear view, etc.


Programming involves the management of complex logical relationships. 
It is more akin to mathematics.  I could continue, but I'll stop here 
and leave it at I'm unconvinced.


Even if I grant the premise, I'll expand on what Timon wrote:
We'd have a lot less accidents if well-designed robots drove our 
vehicles for us (with manual overrides, of course).



B) The description of a() says the return value cannot be null. Then a()
should check its return value before returning or make otherwise sure it
is not null. If it returns null it is a bug. One of the infinite number
of possible bugs that can happen. Again it is not the problem of the
language. The problem of divergence of specification and code is a human
problem that cannot be solved formally. Insistance on formal tools is a
misunderstanding that leads to design bloat and eventually failure (Ada).



As I understand it, you would have written my code snippet this way:

void main()
{
MyType j = b();
assert( j !is null );
assert( j.qux !is null );
assert( j.qux.yarly !is null ); /+ Crash! yarly is null. +/

void* x = a(j);
assert( x !is null );

c();
while(goobledegook)
{
x = p();
assert(x !is null);

d(x);

// Note: be sure to put this one in!
//   The previous dev forgot it...
assert(x !is null);
}
e(x);
}

If you feel that this is misrepresentative, then please provide your 
own.  As it stands: give me non-null 

Re: References in D

2012-10-06 Thread Chad J

On 10/06/2012 04:18 AM, Franciszek Czekała h...@valentimex.com wrote:

B) The description of a() says the return value cannot be null. Then a()
should check its return value before returning or make otherwise sure it
is not null. If it returns null it is a bug. One of the infinite number
of possible bugs that can happen. Again it is not the problem of the
language. The problem of divergence of specification and code is a human
problem that cannot be solved formally. Insistance on formal tools is a
misunderstanding that leads to design bloat and eventually failure (Ada).

D competes directly with C++ as Ada did before. Ada drowned under the
weight of its safety and so will D if it goes the same route. The only
thing needed now are mature compilers and good systems API integration.
If anything I would rather consider removing features from the language
than adding them.




I have another thing to bring up: why the hating on Ada?

Because, if you're hating on Ada because it requires a bunch of extra 
boilerplate and verbosity that most programmers would find unnecessary, 
then I will happily join you in hating on Ada (and Pascal and the like). 
 Keep in mind that one of D's current idiomatic objectives seems to be 
the elimination of as much boilerplate as possible.


I firmly believe that safety and brevity are NOT exclusive to each 
other.  Moreover, they even synergize well if the language and tools are 
designed right: verbose code will be less readable and therefore more 
prone to error.


Re: References in D

2012-10-05 Thread Alex Burton

On Friday, 5 October 2012 at 04:50:18 UTC, Jonathan M Davis wrote:

On Friday, October 05, 2012 05:42:03 Alex Burton wrote:

I realise what is currently the case I am making an argument as
to why I this should be changed (at least for class references 
in

D).


This was talking about C++ references, not D, giving an example 
of how they
can be null even though most people think that they can't be. 
int isn't even

legal syntax in D.


I was talking about both. Regardless of whether the int 
reference or the int * reference was used to assign to memory 
address 0 in Walters example the result is still a crash and will 
be in D with equivalent code using explicit pointers or instances 
of classes (which are always pointers in D).


The crash is a result of two mistakes:

One is the language designer allowing null to be an acceptable 
value for a pointer to an int.
As should be blatently obvious that null is not a pointer to an 
int, but for historical reasons inherited from C (when people 
were just happy to get out of assembly language) it has been 
allowed.


The second mistake is that someone chose to use the language 
feature which clearly makes no sense.

This is bad programming for two reasons:
1) It is logically incorrect to state that 0 is a pointer to 
something.
2) It is a case of using magic numbers in code - an antipattern. 
It is trying to create some universal consensus that the magic 
number 0 means something special. What I am supposed to do with a 
null pointer is not so universal.
Do I construct it ? Do I throw an exception ? Why on earth has 
someone sent me this 0 when my type system specifies I want a 
pointer to an int ?


Regardless, references in D will _never_ be non-nullable. It 
would break too
much code to change it now regardless of whether nullable or 
non-nullable is

better.


I don't think this argument is any more powerful than any of the 
other 'lets remain compatible with C to avoid breakage' ones.


If it were changed there could be compiler errors for 
uninitialised references, and tests for null. These sorts of 
compile time errors are much more preferable than undefined 
behaviour in released code that crashes IMHO.


Alex



Re: References in D

2012-10-05 Thread Regan Heath
On Fri, 05 Oct 2012 05:19:13 +0100, Alex Burton  
alexibureplacewithz...@gmail.com wrote:



On Saturday, 15 September 2012 at 17:51:39 UTC, Jonathan M Davis wrote:

On Saturday, September 15, 2012 19:35:44 Alex Rønne Petersen wrote:

Out of curiosity: Why? How often does your code actually accept null as
a valid state of a class reference?


I have no idea. I know that it's a non-negligible amount of the time,  
though

it's certainly true that they normally have values. But null is how you
indicate that a reference has no value. The same goes for arrays and  
pointers.
Sometimes it's useful to have null and sometimes it's useful to know  
that a
value can't be null. I confess though that I find it very surprising  
how much
some people push for non-nullable references, since I've never really  
found
null to be a problem. Sure, once in a while, you get a null  
pointer/reference
and something blows up, but that's very rare in my experience, so I  
can't help
but think that people who hit issues with null pointers on a regular  
basis are

doing something wrong.

- Jonathan M Davis


In my experience this sort of attutide is not workable in projects with  
more than one developer.


Almost all my work is on projects with multiple developers in C/C++ and  
making extensive use of null.


It all works OK if everyone knows the 'rules' about when to check for  
null and when not to.


As every good C/C++ developer does.  The rule is simple, always check for  
nulls on input passed to public functions/methods.  What you do with  
internal protected and private functions and methods is up to you (I use  
assert).


Telling team members that find bugs caused by your null references that  
they are doing it wrong and next time should check for null is a poor  
substitute for having the language define the rules.


Having language defined rules is a nice added /bonus/ it doesn't let you  
off the hook when it comes to being null safe in your code.


A defensive attitude of checking for null everywhere like I have seen in  
many C++ projects makes the code ugly.


That's a matter of opinion.  I like to see null checks at the top of a  
function or method, it makes it far more likely to be safe and it means I  
can ignore the possibility of null from then on - making the code much  
cleaner.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: References in D

2012-10-05 Thread bearophile

Regan Heath:

That's a matter of opinion.  I like to see null checks at the 
top of a function or method, it makes it far more likely to be 
safe and it means I can ignore the possibility of null from 
then on - making the code much cleaner.


Even more clear/short/light is to not need such checks, and take 
arguments with a light tagging syntax that assures them to be not 
null.


Compare:

void foo1(C1 c1, C2 c2)
in {
assert(c1 !is null);
assert(c2 !is null);
} body {
...
}


With:

void foo2(C1@ c1, C2@ c2) {
...
}


There the @ suffix means not-nullable, it's a D2-compatible 
syntax. In a better designed language, you do the opposite, 
adding ? for nullable reference/pointers, so it becomes (both 
can't be null):


void foo3(C1 c1, C2 c2) {
...
}


Doing this moves the burden of verifying not-nullness out of 
foo2/foo3. If the argument of foo is given to many functions, you 
don't have to test c1 and c2 in every function, saving lines of 
code, space, run-time and avoiding mistakes (and null-related 
bugs are not uncommon).


To create a not-null variable you have to create it assigning it 
to something that is not null (this is the most common case), or 
you have to test it. This test for not-null is similar to the 
tests inside foo1. But such tests tend to be closer to where 
problems are.


A well implemented not-null system asks you to test nullables 
before dereferencing, and keeps track of the nullable/notnull 
type state inside the if statement clauses, avoiding useless 
tests (this means that if you test for null a nullable, inside 
the else clause the state of its type is not-null).


Bye,
bearophile


Re: References in D

2012-10-05 Thread Henning Pohl

On Friday, 5 October 2012 at 13:57:13 UTC, bearophile wrote:

void foo1(C1 c1, C2 c2)
in {
assert(c1 !is null);
assert(c2 !is null);
} body {
...
}


And in public library code, you can't even use assert. You have 
to throw an error/exception. Runtime checks guaranteed even in 
release mode.


Re: References in D

2012-10-05 Thread Jonathan M Davis
On Friday, October 05, 2012 08:45:31 Alex Burton wrote:
 One is the language designer allowing null to be an acceptable
 value for a pointer to an int.
 As should be blatently obvious that null is not a pointer to an
 int, but for historical reasons inherited from C (when people
 were just happy to get out of assembly language) it has been
 allowed.

You are going to find plenty of people who disagree quite strongly with you. 
There are times when having a type be non-nullable is very useful, but there 
are times when having a type be nullable is extremely useful. You seem to 
think that the idea of nullability is bad in the first place, and while some 
people will agree with you, a _lot_ will not. You're fighting a losing battle 
if you're arguing that.

It would be a _huge_ design mistake for a systems language not to have 
nullable pointers. Having non-nullable references or pointers in addition to 
nullable ones might be useful, but not having nullable ones at all would be 
crippling - especially for a systems language.

I think that we're clearly going to have to agree to disagree here.

- Jonathan M Davis


Re: References in D

2012-10-05 Thread Simen Kjaeraas

On 2012-13-05 20:10, Jonathan M Davis jmdavisp...@gmx.com wrote:


It would be a _huge_ design mistake for a systems language not to have
nullable pointers. Having non-nullable references or pointers in  
addition to nullable ones might be useful, but not having nullable ones

at all would be crippling - especially for a systems language.


Indeed. However, given both types, I would argue that non-nullable by
default would go best with the D design guidelines - safe before unsafe,
to be specific.

Of course, given the current state of D, retroactively fitting
non-nullable references/pointers by default is impossible, unwanted,
and simply a bloody stupid idea.

--
Simen


Re: References in D

2012-10-05 Thread Ziad Hatahet
On Fri, Oct 5, 2012 at 11:13 AM, Jonathan M Davis jmdavisp...@gmx.comwrote:

 You are going to find plenty of people who disagree quite strongly with
 you.
 There are times when having a type be non-nullable is very useful, but
 there
 are times when having a type be nullable is extremely useful. You seem to
 think that the idea of nullability is bad in the first place, and while
 some
 people will agree with you, a _lot_ will not. You're fighting a losing
 battle
 if you're arguing that.

 It would be a _huge_ design mistake for a systems language not to have
 nullable pointers. Having non-nullable references or pointers in addition
 to
 nullable ones might be useful, but not having nullable ones at all would be
 crippling - especially for a systems language.

 I think that we're clearly going to have to agree to disagree here.

 - Jonathan M Davis



I do not think he was arguing removing null completely from the type
system. It is just that for the vast majority of the cases, references are
not meant to be null and thus it should be disallowed by default. If you
want to use a nullable reference you have to explicitly ask for such.

--
Ziad


Re: References in D

2012-10-05 Thread Rob T

On Friday, 5 October 2012 at 18:36:07 UTC, Simen Kjaeraas wrote:
Indeed. However, given both types, I would argue that 
non-nullable by
default would go best with the D design guidelines - safe 
before unsafe,

to be specific.



Clearly that would be the case, else we're tossing aside the 
guidlines as they are written. References should be safe first 
which means they must be non-nullable by default, but it also 
should be possible to make references unsafe for those who 
require unsafe abilities (this is also stated in the guidlines). 
It is that sort of general set of guidlines that convinced me 
into investing my time in D, and away from C++ which has the 
opposing set of guidelines. I can do safe coding by default, and 
also unsafe in the normally few places where required.



Of course, given the current state of D, retroactively fitting
non-nullable references/pointers by default is impossible, 
unwanted,

and simply a bloody stupid idea.


Unfortunately, it is that sort of requirement that resulted in 
C++ being not much better than C, but I have to agree that D2 has 
to first solidify itself into a production capable state, this is 
one of the biggest challenges it has right now.


However thinking ahead...

If D as a language is to evolve sensibly, it requires a means to 
make breaking changes, otherwise it will remain stuck with less 
than optimal design choices, and in some cases really bad ones. 
So it seems we do not have a practical means to evolve, other 
than making mediocre changes once every 8 years or so, as we saw 
with the C++11 update. Do we really want that to happen with D?


This is a separate topic, but perhaps using this feature can help 
get around the inability to evolve problem?

http://dlang.org/version.html

--rt



Re: References in D

2012-10-05 Thread Michael
On Saturday, 15 September 2012 at 12:38:53 UTC, Henning Pohl 
wrote:
The way D is dealing with classes reminds me of pointers 
because you can null them. C++'s references cannot (of course 
you can do some nasty casting). So you can be sure to have a 
valid well-defined object. But then there is always the 
ownership problem which renders them more dangerous as they 
seem to be. D resolves this problem using a garbage collector.


So why not combine the advantages of C++ references always 
there guarantee and D's garbage collector and make D's 
references not nullable? If you want it to be nullable, you can 
still make use of real pointers. Pointers can be converted to 
references by implicitly do a runtime check if the pointer is 
not null and references can be converted back to pointers.


I guess you had good reasons about choosing the nullable 
version of D references. Explain it to me, please.


Just some links.
Info at least from 2004.

http://blogs.msdn.com/b/ericlippert/archive/2012/07/17/should-c-warn-on-null-dereference.aspx

http://blogs.msdn.com/b/cyrusn/archive/2005/04/25/411617.aspx

http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/

google site:msdn.com non nullable

Personaly I think that right tool/pattern for right job/task is 
best solution. Maybe problem not in nullable references.




Re: References in D

2012-10-05 Thread Chad J

On 10/05/2012 08:31 AM, Regan Heath wrote:

On Fri, 05 Oct 2012 05:19:13 +0100, Alex Burton
alexibureplacewithz...@gmail.com wrote:


On Saturday, 15 September 2012 at 17:51:39 UTC, Jonathan M Davis wrote:

On Saturday, September 15, 2012 19:35:44 Alex Rønne Petersen wrote:

Out of curiosity: Why? How often does your code actually accept null as
a valid state of a class reference?


I have no idea. I know that it's a non-negligible amount of the time,
though
it's certainly true that they normally have values. But null is how you
indicate that a reference has no value. The same goes for arrays and
pointers.
Sometimes it's useful to have null and sometimes it's useful to know
that a
value can't be null. I confess though that I find it very surprising
how much
some people push for non-nullable references, since I've never really
found
null to be a problem. Sure, once in a while, you get a null
pointer/reference
and something blows up, but that's very rare in my experience, so I
can't help
but think that people who hit issues with null pointers on a regular
basis are
doing something wrong.

- Jonathan M Davis


In my experience this sort of attutide is not workable in projects
with more than one developer.


Almost all my work is on projects with multiple developers in C/C++ and
making extensive use of null.


It all works OK if everyone knows the 'rules' about when to check for
null and when not to.


As every good C/C++ developer does. The rule is simple, always check for
nulls on input passed to public functions/methods. What you do with
internal protected and private functions and methods is up to you (I use
assert).


Telling team members that find bugs caused by your null references
that they are doing it wrong and next time should check for null is a
poor substitute for having the language define the rules.


Having language defined rules is a nice added /bonus/ it doesn't let you
off the hook when it comes to being null safe in your code.


A defensive attitude of checking for null everywhere like I have seen
in many C++ projects makes the code ugly.


That's a matter of opinion. I like to see null checks at the top of a
function or method, it makes it far more likely to be safe and it means
I can ignore the possibility of null from then on - making the code much
cleaner.

R



I find this to be very suboptimal at the least.

This prevents null values from traveling up the stack, but still 
allows them to move down (as return values) and allows them to survive 
multiple unrelated function calls.


It catches null values once they've already ended up in a place they 
shouldn't be.  Too late.


Nulls can also be placed into variables within structs or classes that 
then get passed around.  Checking for those can require some complex 
traversal: impractical for casual one-off checks at the start of a 
function in some cases.


void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from?  Not a. Not p; the while loop 
happened to be never executed.  To say b would be closer, but still 
imprecise.  Actually it was created in the q() function that was called 
by u() that was called by b() which then created a class that held the 
null value and was passed to a() that then dereferenced the class and 
returned the value stored in the class that happened to be null.  nulls 
create very non-local bugs, and that's why they frustrate me to no end 
sometimes.


What I really want to know is where errant null values come FROM.

I also want to know this /at compile time/, because debugging run-time 
errors is time consuming and debugging compile-time errors is not.


The above example could yield the unchecked null assignment at compile 
time if all of the types involved were typed as non-nullable, except for 
the very bare minimum that needs to be nullable.  If something is 
explicitly nullable, then its enclosing function/class is responsible 
for handling null conditions before passing it into non-nullable space. 
 If a function/class with nullable state tries to pass a null value 
into non-nullable space, then it is a bug.  This contains the 
non-locality of null values as much as is reasonably possible.


Additionally, it might be nice to have a runtime nullable type that uses 
its object file's debugging information to remember which 
file/function/line that its null value originated from (if it happens to 
be null at all).  This would make for some even better diagnostics when 
code that HAS to deal with null values eventually breaks and needs to 
dump a stack trace on some poor unsuspecting sap (that isn't me) or 
ideally sends an email to the responsible staff (which is me).




Re: References in D

2012-10-05 Thread Chad J

On 10/03/2012 01:31 PM, Franciszek Czekała h...@valentimex.com wrote:

On Wednesday, 3 October 2012 at 16:33:15 UTC, Simen Kjaeraas wrote:

On 2012-10-03, 18:12, wrote:




They make sure you never pass null to a function that doesn't expect
null - I'd say that's a nice advantage.


No, it is meaningless. If you have a class which is supposed to hold a
prime number and you pass it to a function are you going to check each
time that the value is indeed prime? That would kill the efficiency of
your program guaranteed. So you would be happy to know that the
reference is non-null but you would take it for granted the value is
indeed prime? Does it make any sense?
I maintain that this non-null advantage does not warrant to make the
language more complicated even by a tiny bit. It is dwarfed by normal
considerations related to program correctness.



It would be cool to have templates like this:

51.  bool isPrime(int val)
52.  {
53. ...
54.  }

101. Watch!(int,isPrime) primeNumber = primeGenerator();
102. primeNumber = 8;
103. doStuff();
104. checkPrime(primeNumber); /+ Crash! +/
Error: checkPrime(primeNumber): primeNumber is not prime.
primeNumber: isPrime returned false after assignment at
  (foobar.d, line 102)

~or~

101. Constrain!(int,isPrime) primeNumber = primeGenerator();
102. primeNumber = 8; /+ Crash! +/
103. doStuff();
104. checkPrime(primeNumber);
foobar.d, line 102: isPrime returned false after assignment.

For convenience one could define this:
alias Constrain!(int,isPrime) PrimeInt;

I think this would be sufficient for the cases that are considerable 
less common than errant null references.  I do think these capabilities 
should exist.  Assumptions suck: allowing invalid data to propogate in 
non-local ways is BAD.



With default null references:
A)either null is an expected non-value for the type (like in the chess
example), checking for it is part of normal processing then
B) or null is not a valid value, then there is no need to check for it.
If you get a null reference it is a bug. It is like getting a 15 for
your prime number. You do not put checks like that in your code. You
test your prime generation routine not the consumers. If your function
gets a null reference when it should not, some other part of your
program is buggy. You do not process bugs in your code - you remove them
from it.



Please explain how a program printing
Segmentation fault
tells me where the null came from?

If I'm lucky, I even get a stack trace, which is still not good enough 
in the cases that are actually non-trivial to solve.


My problem with using nullable values /everywhere/ is that they make it 
very difficult to determine exactly what code is /producing/ the null. 
If there's no stack trace information then it isn't even possible to 
know where the consumer is in a lot of cases.



However with D, dereferencing an uninitialized reference is well defined
- null is not random data: you get a well-defined exception and you know
you are dealing with unitialized data. This is easy to fix. You just go
up the stack and check where the reference comes from. Much easier
probably than finding out why your prime numbers turn out to be
divisible by 3. How about introducing some syntax that will rule this out?



You... you... you /JUST/ go up the stack.  Nope.

I've been betrayed by this approach many times in the past.  Can you 
tell? ;)


Copy-pasta from my previous post:

void main()
{
void* x = a(b());
c();
while(goobledegook)
{
x = p();
d(x);
}
e(x); /+ Crash! x is null. +/
}

Where did x's null value come from?  Not a. Not p; the while loop 
happened to be never executed.  To say b would be closer, but still 
imprecise.  Actually it was created in the q() function that was called 
by u() that was called by b() which then created a class that held the 
null value and was passed to a() that then dereferenced the class and 
returned the value stored in the class that happened to be null.  nulls 
create very non-local bugs, and that's why they frustrate me to no end 
sometimes.


(end of copy-pasta)


To quote (loosely) Mr. Walter Bright from another discussion: how many
current bugs in dmd are related to default null references?


I don't know, but when I was trying to debug a certain dmd bug that was 
blocking my progress.  It took a day of figuring out what was creating 
the damn null values.  That could have been much faster.  The bug was 
not caused by null values, but they severely complicated debugging.  So 
no, I don't want to do that work.  I want the compiler to do it for me. 
 (I gave up on fixing that bug because it required rewriting 
non-trivial portions of dmd.)


--

If you have not experienced these frustrations, then you are very 
fortunate.  Please spread your fortune and be more understanding of the 
problems faced by others.


Re: References in D

2012-10-04 Thread Alex Burton alexibu
On Saturday, 15 September 2012 at 21:30:03 UTC, Walter Bright 
wrote:

On 9/15/2012 5:39 AM, Henning Pohl wrote:
The way D is dealing with classes reminds me of pointers 
because you can null
them. C++'s references cannot (of course you can do some nasty 
casting).


Doing null references in C++ is simple:

int *p = NULL;
int r = *p;

r = 3; // crash



IMHO int * p = NULL is a violation of the type system and should 
not compile.

NULL can in no way be considered a pointer to an int.

In the same way this should fail:
Class A
{

}
A a;

Low level programmers might know that references are implemented 
in the microprocessor as memory locations holding addresses of 
other memory locations, but high level programmers should not 
need to know this.


A separate special syntax should be used by low level code in D.
In the vast majority of code, having nullable references is a 
source of bugs.


Passing null to a function expecting a reference/pointer to 
something is equivalent to passing a random number and is the 
same as mixing a biycle into a recipe asking for a cup of sugar.


In cases where you really want to pass a value that could be a 
reference to something or could be null, use a special type that 
allows this.
A clever library writer might be able to implement such a type 
using their low level knowledge of pointers but the rest of us 
should be protected from it.


Re: References in D

2012-10-04 Thread bearophile

Timon Gehr:

To quote (loosely) Mr. Walter Bright from another discussion: 
how many

current bugs in dmd are related to default null references?


More than zero.


A 0 frequency of bugs caused by something can't be enough to 
justify a language feature. You need a high enough frequency :-)


--

Alex Burton:


Doing null references in C++ is simple:

int *p = NULL;
int r = *p;

r = 3; // crash



IMHO int * p = NULL is a violation of the type system and 
should not compile.

NULL can in no way be considered a pointer to an int.


I don't agree. int* is a raw pointer, and a raw pointer is 
allowed to contain a null, so the first line is OK.


The problem is in the second line: in a better designed language 
this line needs to be a compile-time error, because p can be 
null, while r can't be null:


int r = *p;

The language has to force you to initialize the reference with 
something that is valid.


Bye,
bearophile


Re: References in D

2012-10-04 Thread Timon Gehr

On 10/04/2012 01:38 PM, bearophile wrote:

Timon Gehr:


To quote (loosely) Mr. Walter Bright from another discussion: how many
current bugs in dmd are related to default null references?


More than zero.


A 0 frequency of bugs caused by something can't be enough to justify a
language feature. You need a high enough frequency :-)



A correct program contains no errors of any frequency.

Your claim only holds for errors related to the programmer failing to
create a program that parses as he intended it to.

No program errors are 'caused' by invalid references.


--

Alex Burton:
...


(please do not destroy the threading)


Re: References in D

2012-10-04 Thread Jonathan M Davis
On Thursday, October 04, 2012 13:14:00 Alex Burton, @gmail.com wrote:
 On Saturday, 15 September 2012 at 21:30:03 UTC, Walter Bright
 
 wrote:
  On 9/15/2012 5:39 AM, Henning Pohl wrote:
  The way D is dealing with classes reminds me of pointers
  because you can null
  them. C++'s references cannot (of course you can do some nasty
  casting).
  
  Doing null references in C++ is simple:
  
  int *p = NULL;
  int r = *p;
  
  r = 3; // crash
 
 IMHO int * p = NULL is a violation of the type system and should
 not compile.
 NULL can in no way be considered a pointer to an int.

Um. What? It's perfectly legal for pointers to be null. The fact that *p 
doesn't blow up is a bit annoying, but it makes sense from an implementation 
standpoint and doesn't really cost you anything other than a bit of locality 
between the bug and the crash.

 In the same way this should fail:
 Class A
 {
 
 }
 A a;

And why would this fail? It's also perfectly legal.

- Jonathan M Davis


Re: References in D

2012-10-04 Thread Alex Burton
On Thursday, 4 October 2012 at 17:55:45 UTC, Jonathan M Davis 
wrote:
On Thursday, October 04, 2012 13:14:00 Alex Burton, @gmail.com 
wrote:

On Saturday, 15 September 2012 at 21:30:03 UTC, Walter Bright

wrote:
 On 9/15/2012 5:39 AM, Henning Pohl wrote:
 The way D is dealing with classes reminds me of pointers
 because you can null
 them. C++'s references cannot (of course you can do some 
 nasty

 casting).
 
 Doing null references in C++ is simple:
 
 int *p = NULL;

 int r = *p;
 
 r = 3; // crash


IMHO int * p = NULL is a violation of the type system and 
should

not compile.
NULL can in no way be considered a pointer to an int.


Um. What? It's perfectly legal for pointers to be null. The 
fact that *p
doesn't blow up is a bit annoying, but it makes sense from an 
implementation
standpoint and doesn't really cost you anything other than a 
bit of locality

between the bug and the crash.


I realise what is currently the case I am making an argument as 
to why I this should be changed (at least for class references in 
D).



In the same way this should fail:
Class A
{

}
A a;


And why would this fail? It's also perfectly legal.


I realise that this is currently legal, I am proposing that it 
shouldn't be.


If I call a method on reference a (perhaps after it has been 
passed around to a different part of the code) I get an acess 
violation / segfault whatever - Undefined behaviour.

On windows you might get stack unwinding, but otherwise not.
Failing with a memory violation is a bad thing - much worse than 
failing with an exception.
If I press a button in an app and it has a memory violation I can 
loose all my work, and potentially leave parts of a system in 
undefined states , locks on things etc.
If I get an exception, and the code is exception safe, the gui 
can indicate that the button doesn't work right now - maybe 
saying why, and the user can continue without loosing all their 
stuff (hopefully not pressing the same button and finding the 
same bug).


Alex



Re: References in D

2012-10-04 Thread Alex Burton
On Wednesday, 3 October 2012 at 17:37:14 UTC, Franciszek Czekała 
wrote:
On Wednesday, 3 October 2012 at 16:33:15 UTC, Simen Kjaeraas 
wrote:

On 2012-10-03, 18:12,  wrote:



They make sure you never pass null to a function that doesn't 
expect null - I'd say that's a nice advantage.




However with D, dereferencing an uninitialized reference is 
well defined - null is not random data: you get a well-defined 
exception and you know you are dealing with unitialized data.


The above statement is incorrect AFAIK:

class A
{
int x;
void foo()
{
x = 10;
}
}

void main()
{
A a;
a.foo();
}

Results in :
Segmentation fault (core dumped)


Re: References in D

2012-10-04 Thread Alex Burton
On Saturday, 15 September 2012 at 17:51:39 UTC, Jonathan M Davis 
wrote:
On Saturday, September 15, 2012 19:35:44 Alex Rønne Petersen 
wrote:
Out of curiosity: Why? How often does your code actually 
accept null as

a valid state of a class reference?


I have no idea. I know that it's a non-negligible amount of the 
time, though
it's certainly true that they normally have values. But null is 
how you
indicate that a reference has no value. The same goes for 
arrays and pointers.
Sometimes it's useful to have null and sometimes it's useful to 
know that a
value can't be null. I confess though that I find it very 
surprising how much
some people push for non-nullable references, since I've never 
really found
null to be a problem. Sure, once in a while, you get a null 
pointer/reference
and something blows up, but that's very rare in my experience, 
so I can't help
but think that people who hit issues with null pointers on a 
regular basis are

doing something wrong.

- Jonathan M Davis


In my experience this sort of attutide is not workable in 
projects with more than one developer.
It all works OK if everyone knows the 'rules' about when to check 
for null and when not to.
Telling team members that find bugs caused by your null 
references that they are doing it wrong and next time should 
check for null is a poor substitute for having the language 
define the rules.


A defensive attitude of checking for null everywhere like I have 
seen in many C++ projects makes the code ugly.


Re: References in D

2012-10-04 Thread Jonathan M Davis
On Friday, October 05, 2012 05:42:03 Alex Burton wrote:
 I realise what is currently the case I am making an argument as
 to why I this should be changed (at least for class references in
 D).

This was talking about C++ references, not D, giving an example of how they 
can be null even though most people think that they can't be. int isn't even 
legal syntax in D. So, you're responding to the wrong post if you want to talk 
about D references. There are plenty of other places in this thread where such 
a response would make sense, but not here.

Regardless, references in D will _never_ be non-nullable. It would break too 
much code to change it now regardless of whether nullable or non-nullable is 
better. At most, you'll get non-nullable references in addition to nullable 
ones at some point in the future, but that's not going to happen anytime soon. 
The solution that has been decided on is to add a wrapper struct to Phobos 
which allows you to treat a reference as non-nullable. It's far too late to 
change how D works with something so core to the language.

- Jonathan M Davis


Re: References in D

2012-10-03 Thread Ziad Hatahet
On Mon, Sep 24, 2012 at 5:23 AM, Regan Heath re...@netmail.co.nz wrote:

 What I've noticed looking at Java code written by others is that null as a
 possible state is ignored by the vast bulk of the code, which is completely
 the opposite when reviewing C/C++ code where null is checked for and
 handled where applicable.  I think it's a mindset thing brought on by the
 language, or how it's taught, or something.  It seems to me that Java would
 have benefited from non-null references :p


Just because (from your experience) null checks are more prevalent in C or
C++ compared to Java does not mean that any of those languages could not
benefit from non-nullable types. The entire point is to statically prove
that a certain reference/pointer cannot be null. You are better able to
reason about the code, and it is done at compile time with no run time
overhead. Furthermore, you avoid the possibility of forgetting to put in
the checks in the first place.

--
Ziad


Re: References in D

2012-10-03 Thread Franciszek Czekała
On Saturday, 15 September 2012 at 17:12:23 UTC, Jonathan M Davis 
wrote:

On Saturday, September 15, 2012 15:24:27 Henning Pohl wrote:

On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder

wrote:
 On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen 
 wrote:

 […]
 
 Anyway, it's too late to change it now.
 
 I disagree. There are always opportunities to make changes to

 things,
 you just have manage things carefully.

I don't know if people really use the ability of references 
being

null. If so, large amounts of code will be broken.


Of course people use it. Having nullable types is _highly_ 
useful. It would
suck if references were non-nullable. That would be _horrible_ 
IMHO. Having a
means to have non-nullable references for cases where that 
makes sense isn't
necessarily a bad thing, but null is a very useful construct, 
and I'd _hate_

to see normal class references be non-nullable.

- Jonathan M Davis


Agreed. Nullable types are a feature not a bug. There is no need 
to change it. Bugs occur when you do not know the language rules 
and make assumptions instead. This can happen whith any language 
and any rules. As to an example use of nullable references: 
consider a board game (for example chess). The boards has cells 
which can be empty or occupied. Model this with an array of class 
objects  representing pieces. null reference means a cell is not 
occupied. If you want to remove a piece from the board assign 
null to it and GC will take care of the rest. Now, doing this 
with full objects representing empty cells would require needless 
work to define such null objects and would be wasteful of 
memory (typically boards are sparsely populated). Now imagine a 
really big board and every cell holding references to useless 
objects simulating null references. It would not make sense. 
Saying that null references are evil is just propaganda. Let's 
keep D a sane language.




Re: References in D

2012-10-03 Thread Franciszek Czekała
On Wednesday, 3 October 2012 at 08:11:32 UTC, Franciszek Czekała 
wrote:
On Saturday, 15 September 2012 at 17:12:23 UTC, Jonathan M 
Davis wrote:

On Saturday, September 15, 2012 15:24:27 Henning Pohl wrote:

On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder

wrote:
 On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen 
 wrote:

 […]
 
 Anyway, it's too late to change it now.
 
 I disagree. There are always opportunities to make changes 
 to

 things,
 you just have manage things carefully.

I don't know if people really use the ability of references 
being

null. If so, large amounts of code will be broken.


Of course people use it. Having nullable types is _highly_ 
useful. It would
suck if references were non-nullable. That would be _horrible_ 
IMHO. Having a
means to have non-nullable references for cases where that 
makes sense isn't
necessarily a bad thing, but null is a very useful construct, 
and I'd _hate_

to see normal class references be non-nullable.

- Jonathan M Davis


Agreed. Nullable types are a feature not a bug. There is no 
need to change it. Bugs occur when you do not know the language 
rules and make assumptions instead. This can happen whith any 
language and any rules. As to an example use of nullable 
references: consider a board game (for example chess). The 
boards has cells which can be empty or occupied. Model this 
with an array of class objects  representing pieces. null 
reference means a cell is not occupied. If you want to remove a 
piece from the board assign null to it and GC will take care of 
the rest. Now, doing this with full objects representing empty 
cells would require needless work to define such null objects 
and would be wasteful of memory (typically boards are sparsely 
populated). Now imagine a really big board and every cell 
holding references to useless objects simulating null 
references. It would not make sense. Saying that null 
references are evil is just propaganda. Let's keep D a sane 
language.


Regarding my example: we could probably do with a single null 
object stored in all empty cells, but still this would be an 
unnecessary complication.




Re: References in D

2012-10-03 Thread Henning Pohl
On Wednesday, 3 October 2012 at 08:11:32 UTC, Franciszek Czekała 
wrote:
Agreed. Nullable types are a feature not a bug. There is no 
need to change it. Bugs occur when you do not know the language 
rules and make assumptions instead. This can happen whith any 
language and any rules. As to an example use of nullable 
references: consider a board game (for example chess). The 
boards has cells which can be empty or occupied. Model this 
with an array of class objects  representing pieces. null 
reference means a cell is not occupied. If you want to remove a 
piece from the board assign null to it and GC will take care of 
the rest. Now, doing this with full objects representing empty 
cells would require needless work to define such null objects 
and would be wasteful of memory (typically boards are sparsely 
populated). Now imagine a really big board and every cell 
holding references to useless objects simulating null 
references. It would not make sense. Saying that null 
references are evil is just propaganda. Let's keep D a sane 
language.


There is a related question at stackoverflow: 
http://stackoverflow.com/questions/693325/non-nullable-reference-types


As you can see the nullable references are great guy has been 
voted down.


I've written like 5k lines of code in D and never felt the need 
of using null. C++'s std::shared_ptr has the same issue, but at 
least it is called pointer.


Re: References in D

2012-10-03 Thread Maxim Fomin

On Wednesday, 3 October 2012 at 10:41:34 UTC, Henning Pohl wrote:
On Wednesday, 3 October 2012 at 08:11:32 UTC, Franciszek 
Czekała wrote:
Agreed. Nullable types are a feature not a bug. There is no 
need to change it. Bugs occur when you do not know the 
language rules and make assumptions instead. This can happen 
whith any language and any rules. As to an example use of 
nullable references: consider a board game (for example 
chess). The boards has cells which can be empty or occupied. 
Model this with an array of class objects  representing 
pieces. null reference means a cell is not occupied. If you 
want to remove a piece from the board assign null to it and GC 
will take care of the rest. Now, doing this with full objects 
representing empty cells would require needless work to define 
such null objects and would be wasteful of memory (typically 
boards are sparsely populated). Now imagine a really big board 
and every cell holding references to useless objects 
simulating null references. It would not make sense. Saying 
that null references are evil is just propaganda. Let's keep D 
a sane language.


There is a related question at stackoverflow: 
http://stackoverflow.com/questions/693325/non-nullable-reference-types


As you can see the nullable references are great guy has been 
voted down.


I've written like 5k lines of code in D and never felt the need 
of using null. C++'s std::shared_ptr has the same issue, but at 
least it is called pointer.


Since when stackoverflow comment reputation is a word in a 
programming languages? Especially, in issue which is subject for 
human desire to escape from awareness and then complaining about 
arised problems.


Re: References in D

2012-10-03 Thread Franciszek Czekała

On Wednesday, 3 October 2012 at 10:41:34 UTC, Henning Pohl wrote:
On Wednesday, 3 October 2012 at 08:11:32 UTC, Franciszek 
Czekała wrote:
Agreed. Nullable types are a feature not a bug. There is no 
need to change it. Bugs occur when you do not know the 
language rules and make assumptions instead. This can happen 
whith any language and any rules. As to an example use of 
nullable references: consider a board game (for example 
chess). The boards has cells which can be empty or occupied. 
Model this with an array of class objects  representing 
pieces. null reference means a cell is not occupied. If you 
want to remove a piece from the board assign null to it and GC 
will take care of the rest. Now, doing this with full objects 
representing empty cells would require needless work to define 
such null objects and would be wasteful of memory (typically 
boards are sparsely populated). Now imagine a really big board 
and every cell holding references to useless objects 
simulating null references. It would not make sense. Saying 
that null references are evil is just propaganda. Let's keep D 
a sane language.


There is a related question at stackoverflow: 
http://stackoverflow.com/questions/693325/non-nullable-reference-types


As you can see the nullable references are great guy has been 
voted down.


I've written like 5k lines of code in D and never felt the need 
of using null. C++'s std::shared_ptr has the same issue, but at 
least it is called pointer.


The need of using null: Every type needs a default value. null 
supplies it perfectly for all class types in D. And it makes 
sense regardless of what stackoverflow self-appointed political 
commisars want you to believe. Consider my board example: with 
null standing for empty cell when a new board is created as an 
array it is by default empty - in a meaningful state (think of 
games like Go, etc). And at any rate you are going to use a 
property/function like IsEmpty to check for empty cells. Why 
should it be a problem to implement it by comparing with null? If 
anything, it has a chance of being faster than when some other 
concrete reference is used. Without null references you will end 
up defining null objects all over the place (and sometimes it 
may just be impossible when all values are meaningful). Then you 
will have to store them globally and compare everything with 
these objects (named like NullBoard, NullPiece, NullPawn, etc, 
etc because it is ah so much better than just using a single 
keyword null) and if you forget your program will silently churn 
out garbage. With plain null references at least you would get an 
exception. I'd rather see an exception than have a program 
running smoothly with nonsensical results. Like seeing pieces 
vanishing because they are being captured with a null piece 
which I forgot to test for being null. Because, you know, you 
will still have to test conditions in your program to make it 
meaningful, except that it may be a lot more troublesome when 
your program grows x2 in size because of all those safety 
mechanisms.






Re: References in D

2012-10-03 Thread Simen Kjaeraas

On 2012-56-03 14:10,  wrote:


The need of using null: Every type needs a default value.


Good gods, are we not done with this strawman yet?

No, not all types need a default value. In fact, for some types, it is
much better that they don't.


Consider my board example: with null standing for empty cell when a  
new board is created as an array it is by default empty - in a  
meaningful state (think of games like Go, etc).


Yes, null is useful. Nobody is trying to take null away from you.

What we want is the ability to say 'this can never be null', so that we
don't need to check for null over and over.


And at any rate you are going to use a property/function like IsEmpty to  
check for empty cells. Why should it be a problem to implement it by  
comparing with null?


This is not what non-nullable references are about.

When not to use non-nullable references:
 - When the absence of a value is a valid value.
Example:
 - Chess board boxes.

When to use non-nullable references:
 - When the absence of a value is not a valid value.
Example:
 - RenderFoo(NotNull!Foo)


Without null references you will end up defining null objects all over  
the place (and sometimes it may just be impossible when all values are  
meaningful).


No. Please read more about non-nullable references.


Then you will have to store them globally and compare everything with  
these objects (named like NullBoard, NullPiece, NullPawn, etc, etc  
because it is ah so much better than just using a single keyword null)  
and if you forget your program will silently churn out garbage. With  
plain null references at least you would get an exception. I'd rather  
see an exception than have a program running smoothly with nonsensical  
results. Like seeing pieces vanishing because they are being captured  
with a null piece which I forgot to test for being null. Because,  
you know, you will still have to test conditions in your program to make  
it meaningful, except that it may be a lot more troublesome when your  
program grows x2 in size because of all those safety mechanisms.


This... Please... Please, just read more about the topic before
commenting. Please.

--
Simen


Re: References in D

2012-10-03 Thread David Nadlinger
On Wednesday, 3 October 2012 at 12:56:41 UTC, Franciszek Czekała 
wrote:

The need of using null: Every type needs a default value.


This is just plain wrong. There even is a feature in D which 
solely exists for the purpose of allowing struct types _not_ to 
have a default value (@disable this)…


David


Re: References in D

2012-10-03 Thread Franciszek Czekała
On Wednesday, 3 October 2012 at 14:49:36 UTC, Simen Kjaeraas 
wrote:

On 2012-56-03 14:10,  wrote:


The need of using null: Every type needs a default value.


Good gods, are we not done with this strawman yet?

No, not all types need a default value. In fact, for some 
types, it is

much better that they don't.


Consider my board example: with null standing for empty cell 
when a new board is created as an array it is by default empty 
- in a meaningful state (think of games like Go, etc).


Yes, null is useful. Nobody is trying to take null away from 
you.


What we want is the ability to say 'this can never be null', so 
that we

don't need to check for null over and over.


And at any rate you are going to use a property/function like 
IsEmpty to check for empty cells. Why should it be a problem 
to implement it by comparing with null?


This is not what non-nullable references are about.

When not to use non-nullable references:
 - When the absence of a value is a valid value.
Example:
 - Chess board boxes.

When to use non-nullable references:
 - When the absence of a value is not a valid value.
Example:
 - RenderFoo(NotNull!Foo)


Without null references you will end up defining null 
objects all over the place (and sometimes it may just be 
impossible when all values are meaningful).


No. Please read more about non-nullable references.


Then you will have to store them globally and compare 
everything with these objects (named like NullBoard, 
NullPiece, NullPawn, etc, etc because it is ah so much better 
than just using a single keyword null) and if you forget your 
program will silently churn out garbage. With plain null 
references at least you would get an exception. I'd rather see 
an exception than have a program running smoothly with 
nonsensical results. Like seeing pieces vanishing because they 
are being captured with a null piece which I forgot to test 
for being null. Because, you know, you will still have to 
test conditions in your program to make it meaningful, except 
that it may be a lot more troublesome when your program grows 
x2 in size because of all those safety mechanisms.


This... Please... Please, just read more about the topic before
commenting. Please.



When to use non-nullable references:
 - When the absence of a value is not a valid value.


As my comments indicated : the presence of a value does not 
guarantee a valid value by itself. The C++ declaration int n; 
introduces a value, good luck using it. In short, having null 
references is useful (a value outside of the type cannot be 
introduced easily unless the language gives a hand, check eof() 
in C++ character_traits), while forcing non-null references 
hardly offers any significant advantage. Not enough to justify 
complicating the syntax of the language to have it both ways.


Re: References in D

2012-10-03 Thread Simen Kjaeraas

On 2012-10-03, 18:12,  wrote:

As my comments indicated : the presence of a value does not guarantee a  
valid value by itself. The C++ declaration int n; introduces a value,  
good luck using it.


Which is why non-nullable references must not allow the programmer to
declare them without also assigning a valid value (hence the no default
value [note that this is completely different from 'random default value',
which is what you indicate above]). This is easily checkable in a
constructor.


In short, having null references is useful (a value outside of the type  
cannot be introduced easily unless the language gives a hand, check  
eof() in C++ character_traits),


Good gripes, I thought we'd been through this. If you need null, use
it, already! Nobody is trying to take it away, we're suggesting that
most uses of pointers/references should never be null, and such a
constraint can and should be modeled in the type system.

It's also worth pointing out that others have invented (non-null)
sentinel values even for nullable types.



while forcing non-null references hardly offers any significant
advantage.


They make sure you never pass null to a function that doesn't expect
null - I'd say that's a nice advantage.

As you may well be aware, reals are supersets of longs, just like
nullable references are supersets of non-nullable references. If
the argument was that (performance aside) you should simply use
real wherever a long was needed, would you consider that a good idea?
I mean, it's just a matter of making sure you never store a NaN or
other non-integer in it.

The example is admittedly more extreme, but the general idea is the
same.

--
Simen


Re: References in D

2012-10-03 Thread Henning Pohl
On Wednesday, 3 October 2012 at 16:11:53 UTC, Franciszek Czekała 
wrote:

As my comments indicated : the presence of a value does not
guarantee a valid value by itself. The C++ declaration int n; 
introduces a value, good luck using it.

auto c = new Class();

Tell me, does c contain an invalid value now?

In short, having null references is useful (a value outside of 
the type cannot be introduced easily unless the language gives 
a hand, check eof() in C++ character_traits),
Null references are useful, that's right. Nobody wants to take 
them away. Just put something like a questionmark behind the 
reference type to indicate that it's nullable.


while forcing non-null references hardly offers any significant 
advantage.

1) Performance, no or very few null-checks.
2) Code is shorter, looks better, less duplications.
3) Clarity. User of functions know, whether a function can return 
null at compile time.


Not enough to justify complicating the syntax of the language 
to have it both ways.

Not really. It's all about one question mark for example.




Re: References in D

2012-10-03 Thread Maxim Fomin

On Wednesday, 3 October 2012 at 16:36:15 UTC, Henning Pohl wrote:
Just put something like a questionmark behind the reference 
type to indicate that it's nullable.

...

Not really. It's all about one question mark for example.


How much code would be broken by moving nullable references from 
current state to question mark notation?


I expect that non-nullable class objects (called references here) 
addition (if there is no objections to idea in general) would not 
break much code and would not request vast syntax changes. And it 
likely can be done by still defaulting to nullable references. 
For example, it can be done with the help of @nonnullable (like 
immutable) type qualifier and semantic check of operations 
involving references with such qualifier. Anyway, my estimation 
of probability of accepting constructions like type, type*?, 
etc and defaulting to non-null references is very low, at least 
for D2.


Re: References in D

2012-10-03 Thread Henning Pohl

On Wednesday, 3 October 2012 at 16:58:52 UTC, Maxim Fomin wrote:
How much code would be broken by moving nullable references 
from current state to question mark notation?

That's another question :]

I expect that non-nullable class objects (called references 
here) addition (if there is no objections to idea in general) 
would not break much code and would not request vast syntax 
changes. And it likely can be done by still defaulting to 
nullable references. For example, it can be done with the help 
of @nonnullable (like immutable) type qualifier and semantic 
check of operations involving references with such qualifier.
Sounds like a deal for now, but @nonnullable will only work with 
class references and anything else will be an error. So directly 
attaching it to the type (like the questionmark) makes more sense.


Anyway, my estimation of probability of accepting constructions 
like type, type*?, etc and defaulting to non-null 
references is very low, at least for D2.
That's right, but let's use the youth of the language to change 
this. I guess many will hate me if we do so.


Re: References in D

2012-10-03 Thread Henning Pohl

On Wednesday, 3 October 2012 at 16:58:52 UTC, Maxim Fomin wrote:
How much code would be broken by moving nullable references 
from current state to question mark notation?

That's another question :]

I expect that non-nullable class objects (called references 
here) addition (if there is no objections to idea in general) 
would not break much code and would not request vast syntax 
changes. And it likely can be done by still defaulting to 
nullable references. For example, it can be done with the help 
of @nonnullable (like immutable) type qualifier and semantic 
check of operations involving references with such qualifier.
Sounds like a deal for now, but @nonnullable will only work with 
class references and anything else will be an error. So directly 
attaching it to the type (like the questionmark) makes more sense.


Anyway, my estimation of probability of accepting constructions 
like type, type*?, etc and defaulting to non-null 
references is very low, at least for D2.
That's right, but let's use the youth of the language to change 
this. I guess many will hate me if we do so.


Re: References in D

2012-10-03 Thread Henning Pohl

On Wednesday, 3 October 2012 at 16:58:52 UTC, Maxim Fomin wrote:
How much code would be broken by moving nullable references 
from current state to question mark notation?

That's another question :]

I expect that non-nullable class objects (called references 
here) addition (if there is no objections to idea in general) 
would not break much code and would not request vast syntax 
changes. And it likely can be done by still defaulting to 
nullable references. For example, it can be done with the help 
of @nonnullable (like immutable) type qualifier and semantic 
check of operations involving references with such qualifier.
Sounds like a deal for now, but @nonnullable will only work with 
class references and anything else will be an error. So directly 
attaching it to the type (like the questionmark) makes more sense.


Anyway, my estimation of probability of accepting constructions 
like type, type*?, etc and defaulting to non-null 
references is very low, at least for D2.
That's right, but let's use the youth of the language to change 
this. I guess many will hate me if we do so.





Re: References in D

2012-10-03 Thread Franciszek Czekała
On Wednesday, 3 October 2012 at 16:33:15 UTC, Simen Kjaeraas 
wrote:

On 2012-10-03, 18:12,  wrote:



They make sure you never pass null to a function that doesn't 
expect null - I'd say that's a nice advantage.


No, it is meaningless. If you have a class which is supposed to 
hold a prime number and you pass it to a function are you going 
to check each time that the value is indeed prime? That would 
kill the efficiency of your program guaranteed. So you would be 
happy to know that the reference is non-null but you would take 
it for granted the value is indeed prime? Does it make any sense?
I maintain that this non-null advantage does not warrant to 
make the language more complicated even by a tiny bit. It is 
dwarfed by normal considerations related to program correctness.


With default null references:
A)either null is an expected non-value for the type (like in the 
chess example), checking for it is part of normal processing then
B) or null is not a valid value, then there is no need to check 
for it. If you get a null reference it is a bug. It is like 
getting a 15 for your prime number. You do not put checks like 
that in your code. You test your prime generation routine not the 
consumers. If your function gets a null reference when it should 
not, some other part of your program is buggy. You do not process 
bugs in your code - you remove them from it.


However with D, dereferencing an uninitialized reference is well 
defined - null is not random data: you get a well-defined 
exception and you know you are dealing with unitialized data. 
This is easy to fix. You just go up the stack and check where the 
reference comes from. Much easier probably than finding out why 
your prime numbers turn out to be divisible by 3. How about 
introducing some syntax that will rule this out?


To quote (loosely) Mr. Walter Bright from another discussion: how 
many current bugs in dmd are related to default null references?


Re: References in D

2012-10-03 Thread bearophile

Franciszek Czekała:

I maintain that this non-null advantage does not warrant to 
make the language more complicated even by a tiny bit. It is 
dwarfed by normal considerations related to program correctness.


Surely there are more important things to care about. But a 
non-null system has right the purpose of allowing you to take 
more care of the program logic and less about possible null 
values.




With default null references:
A)either null is an expected non-value for the type (like in 
the chess example), checking for it is part of normal 
processing then


A well implemented not-nullable system forces you to verify the 
possible presence of null of nullable values. And if you handle 
the null value in a if clause then the compiler will assume the 
reference is not null in the other clause. This essentially means 
the type of that reference is different inside the two clauses.


A small program that shows two or three important things 
std.typecons.Nullable isn't able to do:



import std.stdio, std.algorithm, std.typecons;

alias Nullable!(int, -1) Position;

void foo(int[] a, Position pos) /*nothrow*/ { // allow this to be 
nothrow

if (pos.isNull) {
return;
} else {
a[pos] = 10; // perform no nullness test here, 
optimization

}
}

void bar(int[] a, Position pos) {
a[pos] = 10; // maybe: require a test here?
}

void main() {
auto data = [1, 2, 3, 4, 5];
auto p = Position(countUntil(data, 7));
foo(data, p);
writeln(data);
}


However with D, dereferencing an uninitialized reference is 
well defined - null is not random data: you get a well-defined 
exception and you know you are dealing with unitialized data. 
This is easy to fix. You just go up the stack and check where 
the reference comes from.


Even better: avoid similar problems statically, with a 
not-nullable extension of the type system, so there is no need to 
debug your program after a run.



Much easier probably than finding out why your prime numbers 
turn out to be divisible by 3. How about introducing some 
syntax that will rule this out?


If D programs contain prime number classes as often as not-null 
references then adding a syntax to statically rule out not-prime 
numbers is an acceptable idea. But the initial assumption is 
false. WalterAndrei have added @disable to try to allow 
programmers to disallow the presence of divisible numbers inside 
instances of a prime class too. But I am not sure the final 
result is good enough.



To quote (loosely) Mr. Walter Bright from another discussion: 
how many current bugs in dmd are related to default null 
references?


DMD source code is a compiler, it's not representative of all 
kinds of D programs. I think there is a class of commercial 
programs, or pointer-heavy programs that enjoy having not-null 
references.


Even if null-related bugs are not common in D code, having a 
language help you reduce one class of bugs helps you program 
faster. I am sometimes able to write working (and almost 
correct) C programs, but D safeties allows me to write them 
faster. If you ask to Scala programmers they will tell you they 
are quite happy to not have to worry much about nulls when they 
write idiomatic Scala code, while they will tell you they have to 
keep more care when they inter-operate with Java code that 
sometimes has nulls.


Bye,
bearophile


Re: References in D

2012-10-03 Thread Henning Pohl
On Wednesday, 3 October 2012 at 17:37:14 UTC, Franciszek Czekała 
wrote:
No, it is meaningless. If you have a class which is supposed to 
hold a prime number and you pass it to a function are you going 
to check each time that the value is indeed prime? That would 
kill the efficiency of your program guaranteed. So you would be 
happy to know that the reference is non-null but you would take 
it for granted the value is indeed prime? Does it make any 
sense?
You have to decide which information should be available at 
compile- and runtime. And that is not easy. In general, it's 
always better to have information present at compile time. To 
come back to your example:


class Number {
this(int i) {
this.i = i;
}

const int i;
}

class PrimeNumber : Number {
this(int i) {
// Check whether i is a prime number or not...


super(i);
}
}

void func(PrimeNumber num);

That's a way to check this at compile time and pass the number 
without runtime checks between prime number functions. But it 
requires i to be constant throughout the lifetime of Number.


It always depends on the context if the use of an extra class 
makes sense.


I maintain that this non-null advantage does not warrant to 
make the language more complicated even by a tiny bit. It is 
dwarfed by normal considerations related to program correctness.


With default null references:
A)either null is an expected non-value for the type (like in 
the chess example), checking for it is part of normal 
processing then

Great, use a question mark.

B) or null is not a valid value, then there is no need to check 
for it. If you get a null reference it is a bug. It is like 
getting a 15 for your prime number. You do not put checks like 
that in your code. You test your prime generation routine not 
the consumers. If your function gets a null reference when it 
should not, some other part of your program is buggy. You do 
not process bugs in your code - you remove them from it.
Contract programming comes into play. But still, you have to 
write contracts containing all those assertions. In libraries you 
can't even use contracts in most cases.


However with D, dereferencing an uninitialized reference is 
well defined - null is not random data: you get a well-defined 
exception and you know you are dealing with unitialized data. 
This is easy to fix. You just go up the stack and check where 
the reference comes from. Much easier probably than finding out 
why your prime numbers turn out to be divisible by 3. How about 
introducing some syntax that will rule this out?

If you write an application, indeed, it's easy to fix.

To quote (loosely) Mr. Walter Bright from another discussion: 
how many current bugs in dmd are related to default null 
references?

DMD is an application, not a library.




Re: References in D

2012-10-03 Thread Franciszek Czekała

On Wednesday, 3 October 2012 at 18:12:51 UTC, Henning Pohl wrote:

class PrimeNumber : Number {
   this(int i) {
   // Check whether i is a prime number or not...
   

   super(i);
   }
}


This is a good example in that validity of the data can be 
checked from inside the class but not the validity of the 
reference. So indeed these two things are not entirely equivalent 
and references need more of the support from the language. Still 
my point is that, in any program lots of things have to be taken 
on faith. Checking and rechecking everything can sink a Titanic. 
A line has to be drawn somewhere. Program correctness will never 
be syntax based only. Default null references are a very 
reasonable approach. C++ does not check anything and is still 
going strong :). Let's not get paranoid. I'd rather see bug-free 
64bit dmd for windows for the current version of the language and 
some libraries for easy windows programming than endless ideas 
for language additions. D already borders on being too complex.


Re: References in D

2012-10-03 Thread Simen Kjaeraas

On 2012-10-03, 19:31,  wrote:


On Wednesday, 3 October 2012 at 16:33:15 UTC, Simen Kjaeraas wrote:

On 2012-10-03, 18:12,  wrote:



They make sure you never pass null to a function that doesn't expect  
null - I'd say that's a nice advantage.


No, it is meaningless. If you have a class which is supposed to hold a  
prime number and you pass it to a function are you going to check each  
time that the value is indeed prime? That would kill the efficiency of  
your program guaranteed. So you would be happy to know that the  
reference is non-null but you would take it for granted the value is  
indeed prime? Does it make any sense?


I don't know the field you're working in, but prime numbers are rarely
a problem in my field. Null pointers, I have to worry about every day.
In our product there is a null pointer bug that has thus far only
occurred on production hardware, where we're not allowed to run
debuggers (gawd dangit), and only once every few weeks. We know where
it happens (third party library) and that non-nullable references would
have ensured it'd never show up.



--
Simen


Re: References in D

2012-10-03 Thread Timon Gehr

On 10/03/2012 07:31 PM, Franciszek Czekała h...@valentimex.com wrote:

...

To quote (loosely) Mr. Walter Bright from another discussion: how many
current bugs in dmd are related to default null references?


More than zero.


Re: References in D

2012-10-03 Thread Timon Gehr

On 10/03/2012 06:59 PM, Maxim Fomin wrote:

On Wednesday, 3 October 2012 at 16:36:15 UTC, Henning Pohl wrote:

Just put something like a questionmark behind the reference type to
indicate that it's nullable.

...

Not really. It's all about one question mark for example.


How much code would be broken by moving nullable references from current
state to question mark notation?



Most of it, and fixing it up quickly may require adding explicit 
assertions together with the question marks.



I expect that non-nullable class objects (called references here)
addition (if there is no objections to idea in general) would not break
much code and would not request vast syntax changes. And it likely can
be done by still defaulting to nullable references. For example, it can
be done with the help of @nonnullable (like immutable) type qualifier
and semantic check of operations involving references with such
qualifier. Anyway, my estimation of probability of accepting
constructions like type, type*?, etc and defaulting to non-null
references is very low, at least for D2.


'non-null reference' is an abominable term. It shouldn't have 'null' in
it. I'd just call it a 'reference'. Having a reference type whose
values always refer to an object, while allowing dereferencing
nullable-by-default references at the same time is not worth the effort.

Imho, either break all code or leave it out.


Re: References in D

2012-10-03 Thread Jonathan M Davis
On Wednesday, October 03, 2012 18:14:46 David Nadlinger wrote:
 On Wednesday, 3 October 2012 at 12:56:41 UTC, Franciszek Czekała
 
 wrote:
  The need of using null: Every type needs a default value.
 
 This is just plain wrong. There even is a feature in D which
 solely exists for the purpose of allowing struct types _not_ to
 have a default value (@disable this)…

Which is a _really_ annoying feature for generic code BTW. But it _is_ 
unfortunately true that some types don't work very well with default values, 
much as it would be ideal for them to have one.

- Jonathan M Davis


Re: References in D

2012-09-25 Thread Mehrdad
On Tuesday, 18 September 2012 at 19:30:24 UTC, Simen Kjaeraas 
wrote:
On Tue, 18 Sep 2012 16:56:31 +0200, Mehrdad 
wfunct...@hotmail.com wrote:


On Saturday, 15 September 2012 at 23:28:36 UTC, Walter Bright 
wrote:
I wouldn't worry about it. I suspect that most C++ 
programmers think that references cannot be null.



Yeah, they can't be null _legally_.

Kind of like how in D you can't strip away const _legally_.

But the compiler doesn't complain if you don't obey the rules.


Well, D at least makes you jump through hoops to strip away 
const,



What does this have to do with const?



while C++ assumes that however stupid the thing you seem to be 
doing is, you probably intended to be that stupid.



Uhm, pardon? Not only is it irrelevant, it's also wrong:
It's harder to do that in C++ than in D.

In C++ you need const_cast (you shouldn't be using a C-style 
casts at all).


In D all you have is cast(), and it's damn easy to strip away 
const, especially when dealing with templates. And the compiler 
doesn't complain either!


Re: References in D

2012-09-25 Thread Mehrdad

On Tuesday, 25 September 2012 at 09:00:39 UTC, Mehrdad wrote:

What does this have to do with const?
...
Not only is it irrelevant, it's also wrong:
It's harder to do that in C++ than in D.



My bad, it's not irrelevant, I misunderstood your reasoning.

It's still wrong though. :)


Re: References in D

2012-09-24 Thread Regan Heath

On Sun, 16 Sep 2012 23:46:34 +0100, deadalnix deadal...@gmail.com wrote:


Le 15/09/2012 19:13, Jonathan M Davis a écrit :

On Saturday, September 15, 2012 15:24:27 Henning Pohl wrote:

On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder

wrote:

On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]


Anyway, it's too late to change it now.


I disagree. There are always opportunities to make changes to
things,
you just have manage things carefully.


I don't know if people really use the ability of references being
null. If so, large amounts of code will be broken.


Of course people use it. Having nullable types is _highly_ useful. It  
would
suck if references were non-nullable. That would be _horrible_ IMHO.  
Having a
means to have non-nullable references for cases where that makes sense  
isn't
necessarily a bad thing, but null is a very useful construct, and I'd  
_hate_

to see normal class references be non-nullable.

- Jonathan M Davis


Years of java have proven me the exact opposite. Nullable is a usefull  
construct, but nullable by default is on the wrong side of the force.


I think it depends on your background.  Most of my experience has been  
with C and C++ and I agree with Jonathan that null is incredibly useful,  
and something I use a lot.  In fact, I am often annoyed that 'int' doesn't  
have an equivalent value, and instead I have to invent a magic number and  
ensure it's never a possible valid value.


What I've noticed looking at Java code written by others is that null as a  
possible state is ignored by the vast bulk of the code, which is  
completely the opposite when reviewing C/C++ code where null is checked  
for and handled where applicable.  I think it's a mindset thing brought on  
by the language, or how it's taught, or something.  It seems to me that  
Java would have benefited from non-null references :p


My uses of null all seem to boil down to being able to represent something  
as being not there yet or not specified etc without having to resort  
to a magic value, or 2nd flag/boolean/parameter.  I find null is a nice  
clean way to do this.


As to whether it should be the default or not.. well, you might have a  
point there.  I think I probably want to use null less than otherwise.


But, all we need is a compiler which says Oi, you haven't initialised  
this forcing me to explicitly set it to null where desired, or a valid  
value and problem solved, right?  That combined with a construct like  
NotNull!(T) which would assert in debug that the reference is not null and  
you can basically stop doing null checks in release code.  Win win, right?


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: References in D

2012-09-24 Thread bearophile

Regan Heath:

In fact, I am often annoyed that 'int' doesn't have an 
equivalent value, and instead I have to invent a magic number 
and ensure it's never a possible valid value.


Try to start using Nullable of Phobos:

http://dlang.org/phobos/std_typecons.html#Nullable

Bye,
bearophile


Re: References in D

2012-09-24 Thread Regan Heath
On Mon, 24 Sep 2012 13:30:29 +0100, bearophile bearophileh...@lycos.com  
wrote:



Regan Heath:

In fact, I am often annoyed that 'int' doesn't have an equivalent  
value, and instead I have to invent a magic number and ensure it's  
never a possible valid value.


Try to start using Nullable of Phobos:

http://dlang.org/phobos/std_typecons.html#Nullable


In C? :p

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: References in D

2012-09-24 Thread Simen Kjaeraas
On Mon, 24 Sep 2012 14:38:56 +0200, Regan Heath re...@netmail.co.nz  
wrote:


On Mon, 24 Sep 2012 13:30:29 +0100, bearophile  
bearophileh...@lycos.com wrote:



Regan Heath:

In fact, I am often annoyed that 'int' doesn't have an equivalent  
value, and instead I have to invent a magic number and ensure it's  
never a possible valid value.


Try to start using Nullable of Phobos:

http://dlang.org/phobos/std_typecons.html#Nullable


In C? :p


Worth a try. :p


--
Simen


Re: References in D

2012-09-18 Thread Mehrdad
On Saturday, 15 September 2012 at 23:28:36 UTC, Walter Bright 
wrote:
I wouldn't worry about it. I suspect that most C++ programmers 
think that references cannot be null.



Yeah, they can't be null _legally_.

Kind of like how in D you can't strip away const _legally_.

But the compiler doesn't complain if you don't obey the rules.


Re: References in D

2012-09-18 Thread Simen Kjaeraas

On Tue, 18 Sep 2012 16:56:31 +0200, Mehrdad wfunct...@hotmail.com wrote:


On Saturday, 15 September 2012 at 23:28:36 UTC, Walter Bright wrote:
I wouldn't worry about it. I suspect that most C++ programmers think  
that references cannot be null.



Yeah, they can't be null _legally_.

Kind of like how in D you can't strip away const _legally_.

But the compiler doesn't complain if you don't obey the rules.


Well, D at least makes you jump through hoops to strip away const,
while C++ assumes that however stupid the thing you seem to be
doing is, you probably intended to be that stupid.

--
Simen


Re: References in D

2012-09-17 Thread Namespace
On Monday, 17 September 2012 at 00:22:52 UTC, Jonathan M Davis 
wrote:

On Monday, September 17, 2012 00:43:50 deadalnix wrote:

It shouldn't be that hard to create a Nullable!T template.


We have one, and it would be wasteful to use that for 
references or pointers
when they're naturally nullable (though you're more or less 
forced to if you
want a truly nullable array thanks to the nonsense that empty 
arrays and null
arrays are considered equal). You're forced to have a separate 
boolean value
indicating whether it's null or not. That might make sense for 
an int, since
it can't be null, but pointers and references _can_ be and are 
in every type

system that I've ever used.

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the 
pull request

with it needed more work, and it hasn't been resubmitted yet.

- Jonathan M Davis


Instead of NonNullable a built-in operator would be preferable. 
Because it seems as though many would like to have something.


Short example:

void foo(Foo f) { }
void main() {
Foo f1; // -- error, not-null references declared, but not 
assigned.

Foo f2; // -- ok

foo(f1); // -- we can trust, f1 has a valid value
foo(f2); /* we cannot trust, the compiler checks at runtime, 
if f2 has a valid value.*/


Re: References in D

2012-09-17 Thread deadalnix

Le 17/09/2012 02:23, Jonathan M Davis a écrit :

On Monday, September 17, 2012 00:43:50 deadalnix wrote:

It shouldn't be that hard to create a Nullable!T template.


We have one, and it would be wasteful to use that for references or pointers
when they're naturally nullable (though you're more or less forced to if you
want a truly nullable array thanks to the nonsense that empty arrays and null
arrays are considered equal). You're forced to have a separate boolean value
indicating whether it's null or not. That might make sense for an int, since
it can't be null, but pointers and references _can_ be and are in every type
system that I've ever used.



And this have proven to be an important source of problem in mostly all 
languages.



Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


Re: References in D

2012-09-17 Thread Jonathan M Davis
On Monday, September 17, 2012 12:52:52 deadalnix wrote:
 Le 17/09/2012 02:23, Jonathan M Davis a écrit :
  Regardless, the solution at this point is going to be to add
  std.typecons.NonNullable. It would be in there already, but the pull
  request with it needed more work, and it hasn't been resubmitted yet.
 
 I don't think this is implementable as a lib in a satisfying way.

Then take it up with Walter and Andrei. After a number of discussions on this 
in the newsgroup (and probably outside it as well), they agreed that it was 
not worth putting non-nullable references in the language and that a library 
solution was sufficient.

- Jonathan M Davis


Re: References in D

2012-09-17 Thread Jonathan M Davis
On Monday, September 17, 2012 13:00:15 deadalnix wrote:
 Don't take this wrong, I do know that this is a major breakage, and
 would arm the language if applied in any short term manner. Still,
 acknowledging error that have been made is usefull.

Not everyone agrees that an error _was_ made. There's a big difference between 
acknoweldging that non-nullable references could be useful and agreeing that 
having nullable references be the default was a bad idea. I very much that it 
will _ever_ happen that non-nullable references would be the default 
(certainly, it will _not_ happen in D2), even if they were added.

- Jonathan M Davis


Re: References in D

2012-09-17 Thread Andrei Alexandrescu

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors. 
Walter never got around to it.


Andrei


Re: References in D

2012-09-17 Thread Russel Winder
On Mon, 2012-09-17 at 09:12 -0400, Andrei Alexandrescu wrote:
 On 9/17/12 6:52 AM, deadalnix wrote:
  Regardless, the solution at this point is going to be to add
  std.typecons.NonNullable. It would be in there already, but the pull
  request
  with it needed more work, and it hasn't been resubmitted yet.
 
 
  I don't think this is implementable as a lib in a satisfying way.
 
 It is, but it needs just a bit of language support in constructors. 
 Walter never got around to it.

Somewhat hypocritically as I cannot volunteer myself just now… just
because Walter didn't get round to it, doesn't mean it can't be done.
People who want the feature should find a way of creating the resource
to make it happen. Four ways: volunteer to do the work themselves; club
together to raise the cash to contract someone to do the work; get an
organization to stump up a person to do the work; get an organization or
seven to stump up cash to contract someone to do the work. There is
nothing quite like providing a pull request to get things moving ;-)

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: References in D

2012-09-17 Thread Timon Gehr

On 09/17/2012 03:33 AM, Jonathan M Davis wrote:

On Monday, September 17, 2012 03:27:10 Timon Gehr wrote:

On 09/17/2012 02:23 AM, Jonathan M Davis wrote:

...  That might make sense for an int, since
it can't be null, but pointers and references _can_ be and are in every
type system that I've ever used.

...


You have claimed multiple times to have used Haskell.


I have, but I've never used pointers in haskell, so if they're non-nullable, I
wouldn't know about it. I believe that everything in Haskell is an immutable
value type as far as what I've dealt with goes.

- Jonathan M Davis



In effect, everything is a non-null reference to mutable, but as
mutation is constrained rather specifically, it is possible to reason
about the behaviour of Haskell programs on a higher level of
abstraction.

 let fib n = if n2 then n else fib (n-1) + fib (n-2)
 let x = fib 30
 let y = x
 let z = x
 y
(delay)
832040
 z
(no delay)
832040



Re: References in D

2012-09-17 Thread Russel Winder
On Mon, 2012-09-17 at 15:49 +0200, Timon Gehr wrote:
[…]
 In effect, everything is a non-null reference to mutable, but as
 mutation is constrained rather specifically, it is possible to reason
 about the behaviour of Haskell programs on a higher level of
 abstraction.
 
   let fib n = if n2 then n else fib (n-1) + fib (n-2)
   let x = fib 30
   let y = x
   let z = x
   y
 (delay)
 832040
   z
 (no delay)
 832040

This is just an artefact of Haskell being a lazy language: x is only
evaluated on demand; the lack of delay is due to the fact the value is
already computed.

Hopefully no-one actually uses that expression for calculating Fibonacci
series for real.

Are you sure the references are to mutable? I had understood Haskell to
be a single assignment to immutable values language.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: References in D

2012-09-17 Thread Alex Rønne Petersen

On 17-09-2012 15:12, Andrei Alexandrescu wrote:

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


What support, exactly?

I mean, we have @disable already.

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: References in D

2012-09-17 Thread Timon Gehr

On 09/17/2012 03:56 PM, Russel Winder wrote:

On Mon, 2012-09-17 at 15:49 +0200, Timon Gehr wrote:
[…]

In effect, everything is a non-null reference to mutable, but as
mutation is constrained rather specifically, it is possible to reason
about the behaviour of Haskell programs on a higher level of
abstraction.

   let fib n = if n2 then n else fib (n-1) + fib (n-2)
   let x = fib 30
   let y = x
   let z = x
   y
(delay)
832040
   z
(no delay)
832040


This is just an artefact of Haskell being a lazy language: x is only
evaluated on demand; the lack of delay is due to the fact the value is
already computed.



The runtime cannot know that the value has already been computed
without keeping state. Identity is important, if I had written
let y = fib 30
let z = fib 30

There would have been a delay two times.


Hopefully no-one actually uses that expression for calculating Fibonacci
series for real.



This worry actually demonstrates my point. Different representations of
the same value are not equivalent in practice.


Are you sure the references are to mutable?


An evaluated expression is not the same thing as a non-evaluated
expression. But the same name is used to refer to both in the example,
ergo the reference is to mutable.


I had understood Haskell to be a single assignment to immutable values language.



That is the abstraction it provides. Values do not change, but their
representations have to, because of the evaluation strategy.


Re: References in D

2012-09-17 Thread Simen Kjaeraas
On Mon, 17 Sep 2012 16:28:46 +0200, Alex Rønne Petersen a...@lycus.org  
wrote:



On 17-09-2012 15:12, Andrei Alexandrescu wrote:

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


What support, exactly?

I mean, we have @disable already.


We have the keyword. It's currently horribly broken.


--
Simen


Re: References in D

2012-09-17 Thread anonymous

On Monday, 17 September 2012 at 13:43:21 UTC, Russel Winder wrote:
Somewhat hypocritically as I cannot volunteer myself just 
now… just
because Walter didn't get round to it, doesn't mean it can't be 
done.
People who want the feature should find a way of creating the 
resource
to make it happen. Four ways: volunteer to do the work 
themselves; club
together to raise the cash to contract someone to do the work; 
get an
organization to stump up a person to do the work; get an 
organization or
seven to stump up cash to contract someone to do the work. 
There is
nothing quite like providing a pull request to get things 
moving ;-)


!




Re: References in D

2012-09-17 Thread Andrei Alexandrescu

On 9/17/12 9:43 AM, Russel Winder wrote:

Somewhat hypocritically as I cannot volunteer myself just now… just
because Walter didn't get round to it, doesn't mean it can't be done.
People who want the feature should find a way of creating the resource
to make it happen. Four ways: volunteer to do the work themselves; club
together to raise the cash to contract someone to do the work; get an
organization to stump up a person to do the work; get an organization or
seven to stump up cash to contract someone to do the work. There is
nothing quite like providing a pull request to get things moving ;-)


Yah indeed. We should improve and systematize the use of DIPs. A DIP 
should have specific states such as RFC, For review, Accepted, 
Implementing, and Implemented.


The acceptance of a DIP means that an implementation of it will be 
merged without objections (save, of course, for implementation-related 
ones).


Committing to such a process ensures that features are specified in good 
level of detail and would encourage people to work on things in 
understanding that their work will bear fruit.



Andrei


Re: References in D

2012-09-17 Thread Andrei Alexandrescu

On 9/17/12 10:28 AM, Alex Rønne Petersen wrote:

On 17-09-2012 15:12, Andrei Alexandrescu wrote:

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


What support, exactly?

I mean, we have @disable already.


Minimal control flow inside constructors. It needs to ensure that all 
NonNull member variables get initialized.


Andrei



Re: References in D

2012-09-17 Thread deadalnix

Le 17/09/2012 15:12, Andrei Alexandrescu a écrit :

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


So it isn't. That was my point. You need the compiler to help you on 
that one.


Re: References in D

2012-09-17 Thread Andrei Alexandrescu

On 9/17/12 12:41 PM, deadalnix wrote:

Le 17/09/2012 15:12, Andrei Alexandrescu a écrit :

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


So it isn't. That was my point. You need the compiler to help you on
that one.


I don't think that was your point. My understanding is that your point 
was that (a) with or without @disable, one cannot implement NonNull 
pointers in the library, and (b) there is need for _specific_ support 
for NonNull in the language. Our position is that NonNull is only one of 
several instances of a much more general pattern, which can be addressed 
with @disable once it is properly tracked inside constructors.



Andrei


Re: References in D

2012-09-17 Thread bearophile

Andrei Alexandrescu:

Our position is that NonNull is only one of several instances 
of a much more general pattern, which can be addressed with 
@disable once it is properly tracked inside constructors.


It's an iterative process: some people invent a feature and put 
in a language, others find it partially implementable in 
libraries and/or useful if generalized. Later someone maybe finds 
that one of the library constructs is so commonly used that 
adding some built-in sugar (like a trailing @) makes code shorter 
and nicer, and so on and on :-)


Bye,
bearophile


Re: References in D

2012-09-17 Thread Andrei Alexandrescu

On 9/17/12 1:15 PM, bearophile wrote:

Andrei Alexandrescu:


Our position is that NonNull is only one of several instances of a
much more general pattern, which can be addressed with @disable once
it is properly tracked inside constructors.


It's an iterative process: some people invent a feature and put in a
language, others find it partially implementable in libraries and/or
useful if generalized. Later someone maybe finds that one of the library
constructs is so commonly used that adding some built-in sugar (like a
trailing @) makes code shorter and nicer, and so on and on :-)

Bye,
bearophile


That sounds nice but it turns out it's not the way @disable came about.

Andrei


Re: References in D

2012-09-17 Thread deadalnix

Le 17/09/2012 13:07, Jonathan M Davis a écrit :

On Monday, September 17, 2012 13:00:15 deadalnix wrote:

Don't take this wrong, I do know that this is a major breakage, and
would arm the language if applied in any short term manner. Still,
acknowledging error that have been made is usefull.


Not everyone agrees that an error _was_ made. There's a big difference between
acknoweldging that non-nullable references could be useful and agreeing that
having nullable references be the default was a bad idea. I very much that it
will _ever_ happen that non-nullable references would be the default
(certainly, it will _not_ happen in D2), even if they were added.

- Jonathan M Davis


Having written a lot of Java code and reviewed even more, I can assure 
you that code written correctly in regard of null is the exception 
rather than the rule.


Plus, all null checks tends to add a runtime cost, and most reference 
will never be null anyway (expect in case of an attack, an invalid use 
of an API, unexpected situation, etc . . .).


The cases where you really want null to be a valid value are the 
exception rather than the rule. And most of the code is written like if 
references couldn't be null.


I saw many Java software explode because of NullPointerException, and it 
was sometime really hard to debug (when race condition get into play for 
instance, as I did in Apache Cayenne).


D have already made a step in a direction similar to non nullable 
references with other types initialization. float initialize to NaN and 
char to invalid codepoints. In other terms poison values. It is useful, 
because it avoid to implement the control flow required to ensure that a 
variable is initialized, but not what you are advocating here (you don't 
seem to consider null as a poison value).


To implement non nullable, whatever the way, such control flow must be 
implemented. And it put the question of default initializer back on the 
table as it open for more advanced way of handling the problem.


Re: References in D

2012-09-17 Thread deadalnix

Le 17/09/2012 19:07, Andrei Alexandrescu a écrit :

On 9/17/12 12:41 PM, deadalnix wrote:

Le 17/09/2012 15:12, Andrei Alexandrescu a écrit :

On 9/17/12 6:52 AM, deadalnix wrote:

Regardless, the solution at this point is going to be to add
std.typecons.NonNullable. It would be in there already, but the pull
request
with it needed more work, and it hasn't been resubmitted yet.



I don't think this is implementable as a lib in a satisfying way.


It is, but it needs just a bit of language support in constructors.
Walter never got around to it.

Andrei


So it isn't. That was my point. You need the compiler to help you on
that one.


I don't think that was your point. My understanding is that your point
was that (a) with or without @disable, one cannot implement NonNull
pointers in the library, and (b) there is need for _specific_ support
for NonNull in the language. Our position is that NonNull is only one of
several instances of a much more general pattern, which can be addressed
with @disable once it is properly tracked inside constructors.


Andrei


Quoting myself : « I don't think this is implementable as a lib in a 
satisfying way. » (assuming, in the current state of things)


I made other point in other posts, but in that one, I just say that non 
nullable references require compiler support in some way compared to 
what we have now.


This support can be reserved to non null, or can be a larger problem 
(like @disable as you mention) that allow to solve the non null problem. 
I don't see how what I write limit things on that topic.


Re: References in D

2012-09-16 Thread Simen Kjaeraas
On Sat, 15 Sep 2012 20:06:01 +0200, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



On Saturday, September 15, 2012 19:57:03 Henning Pohl wrote:

On Saturday, 15 September 2012 at 17:12:23 UTC, Jonathan M Davis

wrote:
 Of course people use it. Having nullable types is _highly_
 useful. It would
 suck if references were non-nullable. That would be _horrible_
 IMHO. Having a
 means to have non-nullable references for cases where that
 makes sense isn't
 necessarily a bad thing, but null is a very useful construct,
 and I'd _hate_
 to see normal class references be non-nullable.

 - Jonathan M Davis

And many usages of null as a state leads to really bad design.
There are functions which behaviour is completly different if you
pass null instead of a valid pointer/reference. An example would
be:

http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceIDs.htm
l


I'd argue that using null for indicating something other than the lack  
of a

value is bad design. But there are plenty of cases where being able to
indicate that there is no value is useful. And if a function requires  
that a
pointer or reference or array or whatever have a value, then there's  
always
DbC or exceptions. Just because someone can misuse a feature doesn't  
mean that

a feature shouldn't be there.


The want for non-nullable pointers and references does not mean nullable
ones should go - far from it. But using nullable pointers where only non-
null values are meaningful is like a function taking a float and working
only when the value is an integer. We're not saying floats are bad,
we're saying 'if your function only works with integers, then use an int'.

--
Simen


Re: References in D

2012-09-16 Thread Peter Alexander
On Saturday, 15 September 2012 at 23:34:44 UTC, Jonathan M Davis 
wrote:

On Saturday, September 15, 2012 16:29:32 Walter Bright wrote:
I wouldn't worry about it. I suspect that most C++ programmers 
think that
references cannot be null. C++ is a complex language, and 
invites

assumptions about it that are not so.


It's stuff like that that makes it so that I'll probably never 
claim that I'm
an expert in C++ even though I'm probably one of the more 
knowledgeable about
it where I work. Even if you think you know it really well, 
there's always

_something_ that you miss.

- Jonathan M Davis


My favourite C++ wtf:

struct Foo
{
template int x, int y int fun(bool c) { return c ? x : y; }
};

struct Bar
{
int fun;
};

template typename T
int madness()
{
return T().fun1, 2(true);
}

The WTF: madnessFoo doesn't compile, but madnessBar does 
(with a warning).




Re: References in D

2012-09-16 Thread Jacob Carlborg

On 2012-09-15 23:30, Walter Bright wrote:


Doing null references in C++ is simple:

int *p = NULL;
int r = *p;

r = 3; // crash


Won't that crash at the first assignment of r, since you dereferencing 
a null pointer?.


--
/Jacob Carlborg


Re: References in D

2012-09-16 Thread Alex Rønne Petersen

On 16-09-2012 13:33, Jacob Carlborg wrote:

On 2012-09-15 23:30, Walter Bright wrote:


Doing null references in C++ is simple:

int *p = NULL;
int r = *p;

r = 3; // crash


Won't that crash at the first assignment of r, since you dereferencing
a null pointer?.



Nope, since in this context you're assigning it to an int. So it really 
just means r = p if you assume that references are just pointers 
(which they are in most implementations).


D works like this too, if you pass a *p to a ref parameter and such.

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: References in D

2012-09-16 Thread Jacob Carlborg

On 2012-09-16 13:47, Alex Rønne Petersen wrote:


Nope, since in this context you're assigning it to an int. So it really
just means r = p if you assume that references are just pointers
(which they are in most implementations).


Ah, I didn't think of that.

--
/Jacob Carlborg


Re: References in D

2012-09-16 Thread deadalnix

Le 15/09/2012 16:23, Alex Rønne Petersen a écrit :

On 15-09-2012 15:24, Henning Pohl wrote:

On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder wrote:

On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]


Anyway, it's too late to change it now.


I disagree. There are always opportunities to make changes to things,
you just have manage things carefully.


I don't know if people really use the ability of references being null.
If so, large amounts of code will be broken.

The best way to stay tuned for that change is to always pray references
to be valid, thus to do no explicit runtime checks.

Are you using reference runtime checks in your current code?


D has null references, so I use them. I would prefer option types, but
they are too verbose in D as things stand.



It shouldn't be that hard to create a Nullable!T template.


Re: References in D

2012-09-16 Thread deadalnix

Le 15/09/2012 19:13, Jonathan M Davis a écrit :

On Saturday, September 15, 2012 15:24:27 Henning Pohl wrote:

On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder

wrote:

On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]


Anyway, it's too late to change it now.


I disagree. There are always opportunities to make changes to
things,
you just have manage things carefully.


I don't know if people really use the ability of references being
null. If so, large amounts of code will be broken.


Of course people use it. Having nullable types is _highly_ useful. It would
suck if references were non-nullable. That would be _horrible_ IMHO. Having a
means to have non-nullable references for cases where that makes sense isn't
necessarily a bad thing, but null is a very useful construct, and I'd _hate_
to see normal class references be non-nullable.

- Jonathan M Davis


Years of java have proven me the exact opposite. Nullable is a usefull 
construct, but nullable by default is on the wrong side of the force.


Re: References in D

2012-09-16 Thread Jonathan M Davis
On Sunday, September 16, 2012 12:08:52 Peter Alexander wrote:
 My favourite C++ wtf:
 
 struct Foo
 {
  template int x, int y int fun(bool c) { return c ? x : y; }
 };
 
 struct Bar
 {
  int fun;
 };
 
 template typename T
 int madness()
 {
  return T().fun1, 2(true);
 }
 
 The WTF: madnessFoo doesn't compile, but madnessBar does
 (with a warning).

Ouch. I assume that that's due to the two-pass template lookup nonsense (or 
whatever the exact name is), which means that that probably won't even behave 
the same across compilers, since not all compilers implement that the same way 
(most notably, Microsoft specifically echoues it in favor of a scheme that 
makes more sense, though it's still a bad idea, since it's non-standard). 
Thank goodness that D didn't follow C++'s example on _that_ one.

- Jonathan M Davis


Re: References in D

2012-09-16 Thread Jonathan M Davis
On Monday, September 17, 2012 00:43:50 deadalnix wrote:
 It shouldn't be that hard to create a Nullable!T template.

We have one, and it would be wasteful to use that for references or pointers 
when they're naturally nullable (though you're more or less forced to if you 
want a truly nullable array thanks to the nonsense that empty arrays and null 
arrays are considered equal). You're forced to have a separate boolean value 
indicating whether it's null or not. That might make sense for an int, since 
it can't be null, but pointers and references _can_ be and are in every type 
system that I've ever used.

Regardless, the solution at this point is going to be to add 
std.typecons.NonNullable. It would be in there already, but the pull request 
with it needed more work, and it hasn't been resubmitted yet.

- Jonathan M Davis


Re: References in D

2012-09-16 Thread Timon Gehr

On 09/17/2012 02:23 AM, Jonathan M Davis wrote:

...  That might make sense for an int, since
it can't be null, but pointers and references _can_ be and are in every type
system that I've ever used.
...


You have claimed multiple times to have used Haskell.



Re: References in D

2012-09-16 Thread Jonathan M Davis
On Monday, September 17, 2012 03:27:10 Timon Gehr wrote:
 On 09/17/2012 02:23 AM, Jonathan M Davis wrote:
  ...  That might make sense for an int, since
  it can't be null, but pointers and references _can_ be and are in every
  type system that I've ever used.
 
 ...
 
 You have claimed multiple times to have used Haskell.

I have, but I've never used pointers in haskell, so if they're non-nullable, I 
wouldn't know about it. I believe that everything in Haskell is an immutable 
value type as far as what I've dealt with goes.

- Jonathan M Davis


Re: References in D

2012-09-15 Thread Alex Rønne Petersen

On 15-09-2012 14:39, Henning Pohl wrote:

The way D is dealing with classes reminds me of pointers because you can
null them. C++'s references cannot (of course you can do some nasty
casting). So you can be sure to have a valid well-defined object. But
then there is always the ownership problem which renders them more
dangerous as they seem to be. D resolves this problem using a garbage
collector.

So why not combine the advantages of C++ references always there
guarantee and D's garbage collector and make D's references not
nullable? If you want it to be nullable, you can still make use of real
pointers. Pointers can be converted to references by implicitly do a
runtime check if the pointer is not null and references can be converted
back to pointers.

I guess you had good reasons about choosing the nullable version of D
references. Explain it to me, please.


D references are not like C++ references *at all*. Reference types in D 
are always classes - no exceptions. When you just need to pass something 
by reference down the call stack and be sure you have no null 
references, you can use 'ref'.


But this being said, I agree that references being nullable by default 
is hurtful. It allows any object reference to have an invalid state even 
though in 99% of cases, that doesn't make sense. It's a giant hole in 
the type system that many new languages have gotten rid of very early 
(forcing the programmer to use explicit option/nullable types).


The way references work in D is pretty much inherited from Java/C#.

http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare

Anyway, it's too late to change it now.

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: References in D

2012-09-15 Thread Russel Winder
On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]
 
 Anyway, it's too late to change it now.

I disagree. There are always opportunities to make changes to things,
you just have manage things carefully. 

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: References in D

2012-09-15 Thread Namespace

That is the one thing I miss also.
The solution until now is to use a wrapper struct around a class, 
but that is _very_ annoying and a good language should have 
something on their own.


But it is right, for D2 this mistake is going to long as you can 
change it so soon.
But maybe a Syntax like in C++ could help: If you want a not 
nullable reference use : void foo(Foo f) { and if you want a 
nullable Reference do nothing extra.
I still work on a (pre)compiler that converts statements like 
Foo f into Ref!Foo but I think D should do this on their own.


Re: References in D

2012-09-15 Thread Henning Pohl
On Saturday, 15 September 2012 at 12:49:23 UTC, Russel Winder 
wrote:

On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]


Anyway, it's too late to change it now.


I disagree. There are always opportunities to make changes to 
things,

you just have manage things carefully.


I don't know if people really use the ability of references being 
null. If so, large amounts of code will be broken.


The best way to stay tuned for that change is to always pray 
references to be valid, thus to do no explicit runtime checks.


Are you using reference runtime checks in your current code?


Re: References in D

2012-09-15 Thread Maxim Fomin
On Saturday, 15 September 2012 at 12:38:53 UTC, Henning Pohl 
wrote:
The way D is dealing with classes reminds me of pointers 
because you can null them. C++'s references cannot (of course 
you can do some nasty casting). So you can be sure to have a 
valid well-defined object. But then there is always the 
ownership problem which renders them more dangerous as they 
seem to be. D resolves this problem using a garbage collector.


So why not combine the advantages of C++ references always 
there guarantee and D's garbage collector and make D's 
references not nullable? If you want it to be nullable, you can 
still make use of real pointers. Pointers can be converted to 
references by implicitly do a runtime check if the pointer is 
not null and references can be converted back to pointers.


I guess you had good reasons about choosing the nullable 
version of D references. Explain it to me, please.


Completely disagree. By the way, you are mixing references and 
classes.

struct S {}

void foo(ref S s); // cannot pass null pointer S* or null - 
always there


Re: References in D

2012-09-15 Thread Maxim Fomin
On Saturday, 15 September 2012 at 12:43:22 UTC, Alex Rønne 
Petersen wrote:
But this being said, I agree that references being nullable by 
default is hurtful. It allows any object reference to have an 
invalid state even though in 99% of cases, that doesn't make 
sense. It's a giant hole in the type system that many new 
languages have gotten rid of very early (forcing the programmer 
to use explicit option/nullable types).


Are speaking about classes? Then how they can be initialized 
(except for null and other existing object)?





Re: References in D

2012-09-15 Thread Simen Kjaeraas
On Sat, 15 Sep 2012 15:32:35 +0200, Maxim Fomin ma...@maxim-fomin.ru  
wrote:



On Saturday, 15 September 2012 at 12:38:53 UTC, Henning Pohl wrote:
The way D is dealing with classes reminds me of pointers because you  
can null them. C++'s references cannot (of course you can do some nasty  
casting). So you can be sure to have a valid well-defined object. But  
then there is always the ownership problem which renders them more  
dangerous as they seem to be. D resolves this problem using a garbage  
collector.


So why not combine the advantages of C++ references always there  
guarantee and D's garbage collector and make D's references not  
nullable? If you want it to be nullable, you can still make use of real  
pointers. Pointers can be converted to references by implicitly do a  
runtime check if the pointer is not null and references can be  
converted back to pointers.


I guess you had good reasons about choosing the nullable version of D  
references. Explain it to me, please.


Completely disagree. By the way, you are mixing references and classes.
struct S {}

void foo(ref S s); // cannot pass null pointer S* or null - always  
there


void bar( ref int n ) {
n = 3;
}

void main( ) {
int* p = null;
bar( *p );
}

Good luck.

Of course, it's not that obvious in production code, but I've had this
happen to me in C++, and - obviously - it can happen in D, too.

--
Simen


Re: References in D

2012-09-15 Thread Henning Pohl

On Saturday, 15 September 2012 at 13:36:00 UTC, Maxim Fomin wrote:
On Saturday, 15 September 2012 at 12:43:22 UTC, Alex Rønne 
Petersen wrote:
But this being said, I agree that references being nullable by 
default is hurtful. It allows any object reference to have an 
invalid state even though in 99% of cases, that doesn't make 
sense. It's a giant hole in the type system that many new 
languages have gotten rid of very early (forcing the 
programmer to use explicit option/nullable types).


Are speaking about classes? Then how they can be initialized 
(except for null and other existing object)?


When you want it to be initialized with null, use a pointer. Else 
you can use something like this:


class AClass {
this(BClass bclass = new BClass) {
_class = bclass;
}

BClass _class;  
}

By the way, a pointer holds two pieces information:
1) If there is an object available
2) If so, the object itself

In most cases, you only need the second one and the if is 
redunant.


Re: References in D

2012-09-15 Thread Maxim Fomin
On Saturday, 15 September 2012 at 13:49:02 UTC, Simen Kjaeraas 
wrote:
void foo(ref S s); // cannot pass null pointer S* or null - 
always there


void bar( ref int n ) {
n = 3;
}

void main( ) {
int* p = null;
bar( *p );
}

Good luck.

Of course, it's not that obvious in production code, but I've 
had this

happen to me in C++, and - obviously - it can happen in D, too.


The problem happens because you deliberately passed hidden null 
pointer. And in real code it could crash after dereferencing and 
before passing to bar, if accessed (meaning that problem is in 
erroneous pointer usage, not accepting ints through reference in 
bar). Certainly, it is possible to break even in such cases, as 
well as in other parts of the language which doesn't necessarily 
mean that such parts of the language are broken. What I was 
talking about is:


void bar( ref int n ) {
n = 3;
}

void main( ) {
int* p = null;
bar(p); // error
bar(null); //error
}



Re: References in D

2012-09-15 Thread Simen Kjaeraas
On Sat, 15 Sep 2012 14:39:49 +0200, Henning Pohl henn...@still-hidden.de  
wrote:


The way D is dealing with classes reminds me of pointers because you can  
null them. C++'s references cannot (of course you can do some nasty  
casting). So you can be sure to have a valid well-defined object. But  
then there is always the ownership problem which renders them more  
dangerous as they seem to be. D resolves this problem using a garbage  
collector.


So why not combine the advantages of C++ references always there  
guarantee and D's garbage collector and make D's references not  
nullable? If you want it to be nullable, you can still make use of real  
pointers. Pointers can be converted to references by implicitly do a  
runtime check if the pointer is not null and references can be converted  
back to pointers.


I guess you had good reasons about choosing the nullable version of D  
references. Explain it to me, please.


Let's start by defining the different types of references D has:

1) Parameter storage class 'ref'. Used when passing an argument by
   reference. Example:
  void foo(ref int n);

2) Class references. Used whenever you have a class. Example:
  auto a = new MyClass();

3) Ref return. Kinda like #1, but for return values. Example:
  ref int bar( );

4) Pointers. Yeah, they're a kind of reference, with the internal
   workings all laid out for anyone to see. Example:
   int* p = new int;

5) Template alias parameters. Let's ignore those for this discussion.

6) Smart pointers of various kinds. Also ignorable for this discussion.

Now, you want #2 to work more like #1, right?

#2 works in some ways like pointers(#4). Most notably, you can have a null
class reference. It's only lately we have gotten support in the language  
for

disabling default constructors of structs (and there are still bugs with
that), allowing non-null pointers and references to be implemented in the
library.

The reason for that can be explained mostly in that Walter did not believe
non-nullable references were that important. The reason it has not become
the default as his understanding has come, is probably because it would be
a very disruptive change of the language, and break *all* code ever written
in D.

Perhaps in D3, though.

--
Simen


Re: References in D

2012-09-15 Thread Simen Kjaeraas
On Sat, 15 Sep 2012 16:06:38 +0200, Maxim Fomin ma...@maxim-fomin.ru  
wrote:



On Saturday, 15 September 2012 at 13:49:02 UTC, Simen Kjaeraas wrote:
void foo(ref S s); // cannot pass null pointer S* or null - always  
there


void bar( ref int n ) {
n = 3;
}

void main( ) {
int* p = null;
bar( *p );
}

Good luck.

Of course, it's not that obvious in production code, but I've had this
happen to me in C++, and - obviously - it can happen in D, too.


The problem happens because you deliberately passed hidden null pointer.


In this very specific example, yes. In my case it happened because I
called a function with a vector of pointers to some class, some of which
were null, and that function did not expect nulls in the vector, passing
them on as references to null.


And in real code it could crash after dereferencing and before passing  
to bar, if accessed (meaning that problem is in erroneous pointer usage,  
not accepting ints through reference in bar). Certainly, it is possible  
to break even in such cases, as well as in other parts of the language  
which doesn't necessarily mean that such parts of the language are  
broken. What I was talking about is:


void bar( ref int n ) {
 n = 3;
}

void main( ) {
 int* p = null;
 bar(p); // error
 bar(null); //error
}


But that's like saying bar(int n) doesn't accept null as a parameter - of
course it doesn't - int and int* are different types.

What I'm saying is references may be a bit safer than pointers, but the
'guarantee' that they're not null pointers in disguise is a lie.

--
Simen


Re: References in D

2012-09-15 Thread Alex Rønne Petersen

On 15-09-2012 14:50, Russel Winder wrote:

On Sat, 2012-09-15 at 14:44 +0200, Alex Rønne Petersen wrote:
[…]


Anyway, it's too late to change it now.


I disagree. There are always opportunities to make changes to things,
you just have manage things carefully.



You can't really do this carefully. One way or another, you're going 
to break *tons* of code by removing null references.


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


  1   2   >