Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-24 Thread deadalnix

On Tuesday, 21 May 2013 at 01:34:29 UTC, estew wrote:
But I'm not convinced it would cost us less to have NotNull!T 
and Nullable!T. I feel it is cheaper to mindlessly write if(a 
is null) {} when using pointers than to worry at design time 
what the behaviour of a pointer should be.




As a matter of fact, most reference are never null, or are 
assumed never to be null.


For instance, in DMD2.062, e2ir.c line 869 it is assumed that 
irs-sclosure can't be null, when in fact it can and that lead to 
an ICE (and that isn't the first one, which kind of mitigate the 
strength of the arguement that this rarely happens and is easy to 
fix).


Design time is the second most expensive developer time for us. 
The most expensive dev. time is changing a design that turned 
out to be incorrect, or is now outdated for whatever reason. 
Moving pointer behaviour to be a design time issue rather than 
knowing it could be NULL so check it could increase the 
probability of redesign bugs creeping in.




You may not know if a reference will be nullable or not when you 
write you code at first. With current model, you start writing 
code as if it can't be null, and then later, when you see you in 
fact need null, you now can have surprise breakage anywhere.


With a Nullable, you'll have code breakage that force you to 
handle the null case. This enforce correctness instead of relying 
on faith.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Kenji Hara
I know at least two cases which T.init is commonly used.

1. Inside predicate template for type T.

template isSomething(T) {
enum isSomething = is(typeof({
//T t1;// not good if T is nested struct, or has @disable this()
//T t2 = void; auto x = t2;  // not good if T is non-mutable type
T t = T.init;   // avoid default construct check
...use t...
}));
}

2. Some library utilities that treats object state directly, e.g.
std.conv.emplace

Kenji Hara

2013/5/20 Maxim Fomin ma...@maxim-fomin.ru

 On Monday, 20 May 2013 at 00:55:14 UTC, Kenji Hara wrote:

 Unfortunately this is currently not a bug.
 T.init provides default initialized object image, and it *does not*
 provide default constructed object. The difference is important.

 That is already documented in lanugage reference.
 http://dlang.org/property#init

  Note: .init produces a default initialized object, not default

 constructed. That means using .init is sometimes incorrect.

 1. If T is a nested struct, the context pointer in T.init is null.
 2. If T is a struct which has @disable this();, T.init might return a

 logically incorrect object.

 Kenji Hara


 I think this should be fixed otherwise @disable this() is compromised.
 What is rationale behind allowing .init?




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Maxim Fomin

On Monday, 20 May 2013 at 06:10:22 UTC, Kenji Hara wrote:

I know at least two cases which T.init is commonly used.

1. Inside predicate template for type T.

template isSomething(T) {
enum isSomething = is(typeof({
//T t1;// not good if T is nested struct, or has 
@disable this()
//T t2 = void; auto x = t2;  // not good if T is 
non-mutable type

T t = T.init;   // avoid default construct check
...use t...
}));
}

2. Some library utilities that treats object state directly, 
e.g.

std.conv.emplace

Kenji Hara


I see. But unfortunately this undermines @disable and defeats 
arguments for using it. @disable is another feature (like ref and 
@safe) which cannot be fixed be design.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Peter Alexander

On Sunday, 19 May 2013 at 21:36:17 UTC, Andrei Alexandrescu wrote:
OK, this is sensible. One question - would you be willing to 
type symbols as NullType!T instead of T to avoid these issues?


Good question. Probably not. I think it's one of those things 
were the awkwardness of it not being the default would lead to 
lack of use (in the same way usage of pure suffers from not being 
default).


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Simen Kjaeraas

On Sun, 19 May 2013 21:02:11 +0200, Idan Arye generic...@gmail.com wrote:

I don't see how Option and Maybe would have helped your bug. The problem  
was that somewhere in the code the reference was perceived as null while  
in fact it wasn't


What does that even mean?


- so now it will be perceived as `None`, and you will have the same  
problem.


Except that now the code would be forced to handle the None case. In a way,
having nullable by default is like having a stringly typed system:

function foo( s ) {
   return (s + 4) * 2; // Works great when s == 16, falls dead on its
   // back when s == goobers.
}

function bar( int i ) {
return (i + 4) * 2;
}


These functions look very different. That's because they are. One of them
only takes valid parameters, the other takes any old garbage and barfs
when the wrong garbage is given to it.

Of course, if you have a string, and you want to call bar, you need to
convert the string to an int. So you end up with this:

function baz( string s ) {
return s.parseInt(
i = bar(i),
{ alert(error); });
}

Notice how the parseInt function takes two delegates? One of these
(the first) is only called when the string is valid. The other is only
called if the string is invalid. That way, we can be sure that the
failure case is handled.

Exactly the same would be the case for non-nullable pointers - if you
want to convert a nullable pointer to non-nullable, you *have* to
handle the failure case. No two ways about it.

Now, the same example with class references:

int foo(A a) {
   return a.qux(); // Works great when a == new A(), falls dead on its
   // back when a == null.
}

int bar(NonNull!A a) {
   return a.qux();
}

See how one of these does not blow up in your face (unless you do
something stupid like create a special Nil value that will do exactly
that)? Now, for baz:

int baz(A a) {
return a.match(
  (NonNull!A a) = bar(a),
  (None) = -1
  );
}


And this is the exact problem with nullable by default : plenty of  
stuff ends up be null is some weird situation that almost never occurs  
when they are assumed not to be and the program crashes.  
NullPointerException now return 4 millions result on google, which is  
probably around once per java developers.


This is not a problem with nullable by default - it is a problem with  
implicit default values. null(or Nil, or None) are the only sane default  
values for reference types - I think you would agree that having to  
construct a new blank object as default value for every reference  
variable would be far worse than null...


If you absolutely cannot initialize the pointer to something sensible,
then use a nullable pointer. But if non-nullable pointers are not
available, or are harder to use than nullable pointer, then people will
use nullable pointers even where non-nullable would have been a much
more fitting choice.



It does not solve the bug - it is something you HAVE to do given the  
assumptions. If the reference is not nullable, and you can't set it to  
it's real value until later in the code, then you have to initialize it  
to some temporary value.


I don't know enough about the bug to say such things for sure, but I will
say this: If deadalnix solved the bug, he is likely in a much better
position to say anything about what would solve the problem than the rest
of us.

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Simen Kjaeraas

On Sun, 19 May 2013 20:05:02 +0200, Idan Arye generic...@gmail.com wrote:


These are the assumptions I'm working with:
  - We can't use a nullable reference
  - We can't initialize the reference upon declaration to it's real  
value.


Indeed, if that's the case, then what you're doing is fairly sensible. But
if #2 is true, then #1 should never be true.

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Simen Kjaeraas
On Sun, 19 May 2013 20:23:21 +0200, Walter Bright  
newshou...@digitalmars.com wrote:



On 5/19/2013 5:02 AM, Simen Kjaeraas wrote:

By definition? Pointer semantics are what we choose it to mean.

Of course. But which definition is saner:


For many types, it is extremely useful to have some sort of invalid  
value for it. null fills that role nicely for pointers, just as nan does  
for floating point types, and 0xFF does for UTF-8.


There's not anything insane about it. The Nullable type constructor even  
exists in order to provide such an invalid state for types (like int)  
which normally do not have one.


Yes, I do understand there's a role for pointers which cannot hold the  
invalid value.


I contend that not only is there a role for them, but that most pointers
should never be null. Here's two questions that convinced me:

1. How many functions that take a pointer or class reference make sense
   to call with null in that pointer/reference?

2. If pointers were non-nullable by default, how often would you need to
   reach for the nullable one?

I argued in another post that nullable by default is analogous to using a
string instead of an int - any number representable in an int is
representable in a string, *and* the string can represent error states.
But if you only want valid ints, there's no reason to use a string.

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread estew
I'm surprised people still have problems with null pointers. I 
for one am glad D has null by default makes life easy coming from 
C++ and Java.


I may have missed something but what happens with the following 
code if I could not have a null pointer?


int*[] pntrs = new int*[10];

Would I need to write something like?

Null!(int*)[] pntrs = new Null!(int*)[10];

Personally, I'd rather have null by default as I find it less 
noisy and I don't need it spelled out in the code, it is implied.


No it sound like initalizing something to null, then 
initialize it properly, assume all over the place that it is 
initialized to something else, and in some rare code path it 
blows up.


OK, so the D gurus kindly introduce for us NotNull!T, Maybe!T, 
Option!T and SegFault!T (just for me). Now I want to access a 
pointer, write code using it etc. But I need to manually track at 
development time whether it is NotNull!T, Null!T, Maybe!T, 
Option!T or whatever. I cannot just have a pointer anymore, 
knowing it's initialised to null. Now I realise it needs to 
change from NotNull!T to Maybe!T...great yet more refactoring. Ok 
refactoring done (yay sed!) but you know what, now I need to find 
every access to that pointer and check for null. More error prone 
than this:


If you are in doubt (i.e. most multi-threaded apps) then check if 
null, with the added comfort that D has initialised all pointers 
to NULL for you. If still in doubt, don't use pointers.


If you want non-null pointers (please no) then it is all or 
nothing. Allowing some pointers null and others not, via 
Nullable!T or NotNull!T, immediately adds another layer of 
complexity.


I don't want to hear: D pointers cannot be null...well ok, they 
can sometimes, it depends, you'll have to read the code. But 
don't worry, D is very easy to read...


My 1 cent. Disregard if I have totally misunderstood the thread, 
possible as it is very late! :-)


Cheers,
Stewart


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Dicebot

On Monday, 20 May 2013 at 14:49:32 UTC, estew wrote:
Now I want to access a pointer, write code using it etc. But I 
need to manually track at development time whether it is 
NotNull!T, Null!T, Maybe!T, Option!T or whatever. I cannot just 
have a pointer anymore, knowing it's initialised to null.


Yes and this is awesome. This is correctness enforced by type 
system. Because if you _don't_ track this, you have a possible 
error in your code. Only difference between nullable and 
non-nullable pointers by default is that latter _force_ you to 
write correct code. Which is good.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Byron Heads
On Sun, 19 May 2013 17:36:17 -0400, Andrei Alexandrescu wrote:

 On 5/19/13 4:30 PM, Peter Alexander wrote:
 On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:
 You are blowing it out of proportion. Null references are hardly even
 on the radar of the bug classes I'm encountering in the style of
 programming of the three groups I worked in at Facebook, and also my
 previous employers. People I meet at conferences and consulting gigs
 never mention null references as a real problem, although I very often
 ask about problems. I find it difficult to agree with you just to be
 nice.

 Just because people don't mention them as a problem doesn't mean it
 isn't a problem.

 For what it's worth, null pointers are a real problem in the code I
 work on (games). I don't know exactly what you work on, but I find that
 they are more of a problem in highly stateful, interactive
 applications. Things like generic libraries, utility programs,
 compilers, etc. probably won't see the same problems because they
 aren't very stateful or interactive.

 In my experience, null pointers are easy to fix, but the risk of them
 causes people to litter their code with if (ptr) tests, often with poor
 handling of the failure case, which can cause subtle bugs (no crash,
 but unintended code path).

 Just my 2c.
 
 OK, this is sensible. One question - would you be willing to type
 symbols as NullType!T instead of T to avoid these issues?
 
 Thanks,
 
 Andrei

More boiler plate code for functions that take pointers.

void foo(T)(T t)
if(isPointer!T)
{
static if(isNullable!T)
if(!t) throw 
}

May also introduce then need to check for objects in the init state 
(default state)



outside of NonNull in stdlib, an attribute maybe a possible answer.

void bar(@nonnull SomeClass o)
{
o = foo(); // if foo returns @nonnull, then check is not needed, 
else needs a check added during assignment
}

there are a few compile time checks that can be done to prove o is not 
null, if not the compiler adds runtime checks.

But really, checking for valid input is part of programming, might be 
better to have lint integration that can help find these types of problems



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Andrei Alexandrescu

On 5/19/13 8:46 PM, Steven Schveighoffer wrote:

I just wanted to chime in with this understanding of the bug that I am
reading from deadalnix's descriptions:

SomeObj obj;
shareTheObj(obj); // goes to other threads
obj = new SomeObj; // initialize obj

This is likely simpler than the actual problem, but I think this is the
gist of it.

A Non-Nullable solution WOULD solve the race:

SomeObj obj; // Compiler: nope, can't do that, must initialize it.

Now, with an invalid state not available like null, is the developer
more likely to go through the trouble of building an invalid state for
obj, in order to keep the racy behavior? No. He's just going to move the
initialization:

SomeObj obj = new SomeObj;
shareTheObj(obj);

In essence the point of the anecdote is that a Non-Nullable reference
would have PROMOTED avoiding the race condition -- it would have been
harder to keep the racy behavior.


One can only assume the entire point was to delay initialization of the 
object to its first use/sharing point, so the changed pattern simply 
initializes the object eagerly, thus missing the benefits of the 
pattern. Otherwise that's an instance of the old adage initialize 
variables at the point of definition. That, granted, non-null 
references do help with.



Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Andrei Alexandrescu

On 5/20/13 11:19 AM, Byron Heads wrote:

On Sun, 19 May 2013 17:36:17 -0400, Andrei Alexandrescu wrote:

OK, this is sensible. One question - would you be willing to type
symbols as NullType!T instead of T to avoid these issues?

Thanks,

Andrei


More boiler plate code for functions that take pointers.

void foo(T)(T t)
if(isPointer!T)
{
 static if(isNullable!T)
if(!t) throw 
}


But this goes both ways. Regardless of the default, you'd sometimes need 
to distinguish between cases. You either hurt one half of your cases or 
the other half. In fact you are now showing the case that assumes 
non-nullable being the default.



May also introduce then need to check for objects in the init state
(default state)



outside of NonNull in stdlib, an attribute maybe a possible answer.

void bar(@nonnull SomeClass o)
{
o = foo(); // if foo returns @nonnull, then check is not needed,
else needs a check added during assignment
}

there are a few compile time checks that can be done to prove o is not
null, if not the compiler adds runtime checks.


I think a parameterized type is a better match for non-null because it 
attaches to the type, not the symbol.



But really, checking for valid input is part of programming, might be
better to have lint integration that can help find these types of problems


Agreed.


Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Byron Heads
On Mon, 20 May 2013 11:43:35 -0400, Andrei Alexandrescu wrote:

 On 5/20/13 11:19 AM, Byron Heads wrote:
 On Sun, 19 May 2013 17:36:17 -0400, Andrei Alexandrescu wrote:
 OK, this is sensible. One question - would you be willing to type
 symbols as NullType!T instead of T to avoid these issues?

 Thanks,

 Andrei

 More boiler plate code for functions that take pointers.

 void foo(T)(T t)
  if(isPointer!T)
 {
  static if(isNullable!T)
  if(!t) throw 
 }
 
 But this goes both ways. Regardless of the default, you'd sometimes need
 to distinguish between cases. You either hurt one half of your cases or
 the other half. In fact you are now showing the case that assumes
 non-nullable being the default.
 
 May also introduce then need to check for objects in the init state
 (default state)



 outside of NonNull in stdlib, an attribute maybe a possible answer.

 void bar(@nonnull SomeClass o)
 {
  o = foo(); // if foo returns @nonnull, then check is not needed,
 else needs a check added during assignment }

 there are a few compile time checks that can be done to prove o is not
 null, if not the compiler adds runtime checks.
 
 I think a parameterized type is a better match for non-null because it
 attaches to the type, not the symbol.
 
 But really, checking for valid input is part of programming, might be
 better to have lint integration that can help find these types of
 problems
 
 Agreed.
 
 
 Andrei



What about dealing with externs you want to protect?

extern(C) void foo(@nonnull int* x);

other then that I think the library solution is fine

@nonnull Bar* b = NotNull!(NotNull!Bar) b







Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Simen Kjaeraas
On Sun, 19 May 2013 05:17:57 +0200, Walter Bright  
newshou...@digitalmars.com wrote:



On 5/18/2013 1:39 PM, Walter Bright wrote:

Already reported:

http://d.puremagic.com/issues/show_bug.cgi?id=10115


And Kenji has already posted a fix!

What can I say, other than Awesome!


Great! One more:

http://d.puremagic.com/issues/show_bug.cgi?id=1528

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Simen Kjaeraas
On Mon, 20 May 2013 18:05:18 +0200, Byron Heads byron.he...@gmail.com  
wrote:



What about dealing with externs you want to protect?

extern(C) void foo(@nonnull int* x);


There is nothing stopping you from declaring that with this signature:

extern(C) void foo(NonNull!(int*) x);

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread Bottled Gin

On Monday, 20 May 2013 at 00:55:14 UTC, Kenji Hara wrote:

Unfortunately this is currently not a bug.
T.init provides default initialized object image, and it 
*does not*
provide default constructed object. The difference is 
important.


That is already documented in lanugage reference.
http://dlang.org/property#init


Note: .init produces a default initialized object, not default

constructed. That means using .init is sometimes incorrect.
1. If T is a nested struct, the context pointer in T.init is 
null.
2. If T is a struct which has @disable this();, T.init might 
return a

logically incorrect object.

Kenji Hara



In that case, kindly let me understand why it is not possible to 
allow explicit default constructor for structs given that:


1. The constructor gets called at run time.
2. Is not considered for evaluating S.init (compile time).



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-20 Thread estew

On Monday, 20 May 2013 at 14:57:17 UTC, Dicebot wrote:

On Monday, 20 May 2013 at 14:49:32 UTC, estew wrote:
Now I want to access a pointer, write code using it etc. But I 
need to manually track at development time whether it is 
NotNull!T, Null!T, Maybe!T, Option!T or whatever. I cannot 
just have a pointer anymore, knowing it's initialised to null.


Yes and this is awesome. This is correctness enforced by type 
system. Because if you _don't_ track this, you have a possible 
error in your code. Only difference between nullable and 
non-nullable pointers by default is that latter _force_ you to 
write correct code. Which is good.


True I grant you that, it was late when I posted :-) I've 
actually come around a bit on this after sleeping on it and 
rereading some of the posts. I am starting to like NotNull!T idea 
but I'm a bit hesitant still with Maybe!T, Option!T.


I cannot remember the last time our team had NULL pointer issues. 
We have 102 devs on four integrated products. Big enough to not 
know context your code might be used in nor the implementation 
details of all libraries. The only pointer troubles we see are 
forget to init to NULL or reset to NULL after freeing resources. 
All devs know raw pointers are initialised to NULL. We are C/C++.


So non-null pointers wouldn't make much difference to us here, 
although it may make the code more readable which is always a 
good thing. D needs nullable pointers though, of some form.


But I'm not convinced it would cost us less to have NotNull!T and 
Nullable!T. I feel it is cheaper to mindlessly write if(a is 
null) {} when using pointers than to worry at design time what 
the behaviour of a pointer should be.


Design time is the second most expensive developer time for us. 
The most expensive dev. time is changing a design that turned out 
to be incorrect, or is now outdated for whatever reason. Moving 
pointer behaviour to be a design time issue rather than knowing 
it could be NULL so check it could increase the probability of 
redesign bugs creeping in.


Still, I am loving the discussion in this thread it's very 
interesting from both sides.


Stewart


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Jonathan M Davis
On Saturday, May 18, 2013 22:04:08 Walter Bright wrote:
 On 5/18/2013 9:42 PM, Jonathan M Davis wrote:
  On Saturday, May 18, 2013 21:30:57 Walter Bright wrote:
  On 5/18/2013 9:06 PM, Jonathan M Davis wrote:
  The closest that there is is
  C++'s references, which aren't rebindable and in many ways act more like
  aliases than pointers.
  
  You can trivially create null references in C++:
  
  int* p = NULL;
  int r = *p;
  
  Yes, but they're designed with the idea that they're non-nullable. You
  can't assign NULL to them or check if they're NULL. It's just that it's
  possible to make them NULL by the trick that you just showed.
 
 I don't even think it's a trick, as it can easily happen unintentionally.

Yes, but it's not something that would be done intentionally, and it's 
something that surprises most people. I expect that the vast majority of C++ 
programmers would think that it's impossible before it was explained to them. 
C++ references are usually sold as being non-nullable, and this is arguably a 
hole in their design.

- Jonathan M Davis


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Simen Kjaeraas
On Sun, 19 May 2013 06:57:16 +0200, Walter Bright  
newshou...@digitalmars.com wrote:


The current solution is to rely on faith, and I remember someone  
talking about

that at DConf recently.


Rely on what faith?


void foo(int* p) {} // p must never be null
void foo(NotNull!(int*) p) {}

One of these is tested at compile time, *and* includes valuable
documentation in the signature. The other is either less performant
or buggy.


Now that what other languages does is cleared, let's do some  
consideration on null.


A pointer point on something. For instance, an int* point on an  
integer. null
doesn't point on a integer. Non nullable pointer aren't a restricted  
set of
values, as, by definition, null isn't a value that point to an int.  
That doesn't

stand either.


By definition? Pointer semantics are what we choose it to mean.


Of course. But which definition is saner:

  T* is either a valid pointer to a T, or a value that blows up when used
  in certain ways (but not others).

or

  T* is a valid pointer to T.

Of course, the latter also requires something like Maybe!T:

  Maybe!T is either a valid pointer to a T, or a value on which no
  operations may be performed. In order to gain access to the T, both
  cases have to be handled.

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Simen Kjaeraas
On Sun, 19 May 2013 02:32:49 +0200, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



On Sunday, May 19, 2013 02:22:43 Simen Kjaeraas wrote:

Or... possibly, the current holes in @disable are fixed, and NonNull!T
becomes the default, because we tell people to always use them, rather
than flail our arms and behave like idiots. (regular pointers are
broken, use NonNull!T is a pretty good argument if it's true)


I've never understood why so many people feel that nullable pointers are  
a
problem. Clearly, many people do, but personally, I've rarely had  
problems
with them, and there are plenty of cases where not being to make a  
pointer

null would really suck (which is why we're forced to have
std.typecons.Nullable for non-reference types). I'm not arguing against  
having
non-nullable pointers, but I'd probably almost never use them myself, as  
I
really don't think that they'd be buying me much. In my experince,  
problems

with null pointers are extremely rare and easily caught.


My experience is the complete opposite - I think maybe 20% of bugs at my  
job

are caused by null references. But as you say, they are very easily fixed.

That said, two things to consider:

How many of the functions you write actually need to accept nullable
pointers/references?

If non-nullable was the default, how often would you explicitly ask for a
nullable pointer/reference?

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/19/2013 06:57 AM, Walter Bright wrote:

D already have thing like Nullable in the standard lib. Introducing
Maybe is
also pretty easy. Adding NonNullable in addition to Nullable sound like
something is not quite right.


Nullable is something different - it exists to give a 'null' value to
things that don't have a null representation, like an int.



Type Object ought not to have a null representation either.


C#, for example, has a Nullable type constructor, but it still has
object references that can be null. C# has no standard way to produce a
non-nullable object reference.

There's no non-null wrapper in Java, either.


This limits those languages' static type safety as much as D's.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 12:06:01 UTC, Simen Kjaeraas wrote:
My experience is the complete opposite - I think maybe 20% of 
bugs at my job
are caused by null references. But as you say, they are very 
easily fixed.




Sometime they are super freaking hard. I have a horror story 
debugging Apache Cayenne : http://cayenne.apache.org/ because it 
was throwing NPE on a race condition that would never show up 
once the code is instrumented.


A reference was null for a short moment and then set to 
something. Due to concurrency, in extreme cases it could be seen 
as null where it was assumed everywhere to be set.



That said, two things to consider:

How many of the functions you write actually need to accept 
nullable

pointers/references?

If non-nullable was the default, how often would you explicitly 
ask for a

nullable pointer/reference?


Not that much and I'd rather be warned when it is the case.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 8:55 AM, deadalnix wrote:

On Sunday, 19 May 2013 at 12:06:01 UTC, Simen Kjaeraas wrote:

My experience is the complete opposite - I think maybe 20% of bugs at
my job
are caused by null references. But as you say, they are very easily
fixed.



Sometime they are super freaking hard. I have a horror story debugging
Apache Cayenne : http://cayenne.apache.org/ because it was throwing NPE
on a race condition that would never show up once the code is instrumented.

A reference was null for a short moment and then set to something. Due
to concurrency, in extreme cases it could be seen as null where it was
assumed everywhere to be set.


Sounds like a race problem unrelated to null. With non-null objects the 
race would have manifested itself in a different way, perhaps even more 
pernicious.


Anyhow, this discussion should have finality. We could go on forever 
arguing the usefulness or lack thereof of non-nullable references. They 
didn't catch up in some languages and did in some. My personal opinion 
is nice to have, but not greatly compelling.


It's reasonable to assume no major language changes will accommodate 
non-null references, so the next best thing would be to focus on a 
library solution. As Walter said, a library solution has the perk of 
allowing other interesting restricted types.



Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:
Sounds like a race problem unrelated to null. With non-null 
objects the race would have manifested itself in a different 
way, perhaps even more pernicious.




It is both a race condition and a null problem. And having non 
nullable type would have been a compile time error instead of 
days of debugging.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 9:11 AM, deadalnix wrote:

On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:

Sounds like a race problem unrelated to null. With non-null objects
the race would have manifested itself in a different way, perhaps even
more pernicious.



It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of debugging.


No, the race condition would have stayed.


Andrei



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Idan Arye

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

On 5/19/13 9:11 AM, deadalnix wrote:
On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu 
wrote:
Sounds like a race problem unrelated to null. With non-null 
objects
the race would have manifested itself in a different way, 
perhaps even

more pernicious.



It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of 
debugging.


No, the race condition would have stayed.


Andrei


I believe this claim requires an explanation:

It's a good practice to initialize references(and all other types 
of variables) as soon as possible - and if possible, right away 
in the declaration. If that reference started as null, it's safe 
to assume it was not possible to initialized it at declaration, 
so it was intentionally initialized with null(if there was no 
initialization Java would scream at you).


Now, let's assume that reference was non-nullable. It is safe to 
assume that this change would not remove the obstacle that 
prevented that reference from being initialized right away in the 
declaration - so you still need to initialize it to something 
else - let's call that something `Nil`. Nil is an object that 
tells you that the reference has not yet been initialized.


So, in the original bug the reference could be seen
as null where it was assumed everywhere to be set.. But now we 
don't have null - so that piece of code that thought the 
reference is null would now think that it is... what? The 
initialization value? No! Because we didn't switch from 
initializing the reference with null to initializing it with the 
later initialization value - we couldn't do it. Instead, we had 
to use Nil. So now, the reference 'could be seen as Nil where it 
was assumed everywhere to be set'...


Now, if you are lucky and your Nil is the better-kind-of-null 
that is used in dynamic object oriented languages, you'll get a 
nil exception - which is just as good as null exception. But if 
you are not so lucky, and you had to declare Nil as a blank 
object of the type of that reference, you are going to have 
logical bug, which is far worse than exceptions...


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

On 5/19/13 9:11 AM, deadalnix wrote:

It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of 
debugging.


No, the race condition would have stayed.



That is ridiculous. non nullable would have made the bug non 
existent, and even without race condition the problem would 
exists. a reference is null, it container shared, then set to 
something else. You can put barriers all over the place to make 
that sequentially consistent that it wouldn't change anything and 
the bug would still arise.


You also never provided any convincing solution to the safety 
hole. We can't even add check only on some edges cases as D also 
have values types. The only solution we are left with that is 
really safe is to null check every dereference or give up on 
@safe.


I encourage you to look at this : 
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare


Most new languages removed nullable by default, or limited its 
uses (scala for instance, allow for null for limited scope).


I once again want to get attention on the fact that GC change 
everything in regard to reference, and that the C++ situation is 
a bad example.


Idan Arye  Nil proposal make no sens in a statically typed 
language. And you'll find no better kind of null. We have all 
tools we need in D to work around null in library.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 04:57:15 UTC, Walter Bright wrote:

On 5/18/2013 8:54 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 01:20:31 UTC, Walter Bright wrote:
I understand that. But the rationale you gave for having a 
default constructor

was to be able to disable default construction.


RAII or construction based on template parameters.


I know what default constructors are used for in C++. That 
wasn't what I asked, though. I asked for compelling rationale.




I have bunch of code that goes like :

auto oldVar = var;
scope(exit) var = oldVar;

This is begging for a RAII solution where I pass var as template 
parameter but would require default constructor. This is an 
actual problem I have right now as all save/restore are harder 
and harder to keep in sync for no reason and generate a lot of 
boilerplate.


This is a problem I have right now that default constructor would 
solve, and this isn't the first time I hit that need.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Simen Kjaeraas

On Sun, 19 May 2013 19:12:15 +0200, Idan Arye generic...@gmail.com wrote:

It's a good practice to initialize references(and all other types of  
variables) as soon as possible - and if possible, right away in the  
declaration. If that reference started as null, it's safe to assume it  
was not possible to initialized it at declaration, so it was  
intentionally initialized with null(if there was no initialization Java  
would scream at you).


Now, let's assume that reference was non-nullable. It is safe to assume  
that this change would not remove the obstacle that prevented that  
reference from being initialized right away in the declaration - so you  
still need to initialize it to something else - let's call that  
something `Nil`. Nil is an object that tells you that the reference has  
not yet been initialized.


Uhm, no. Nononono. No. This is a complete and utter fallacy. What you
have just done is define Nullable!(NonNullable!T). I should not have to
explain too closely why this is a bad thing and should not be done.

--
Simen


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Idan Arye

On Sunday, 19 May 2013 at 17:35:43 UTC, deadalnix wrote:
Idan Arye  Nil proposal make no sens in a statically typed 
language. And you'll find no better kind of null. We have all 
tools we need in D to work around null in library.


That's not the point. The point is that if you couldn't 
initialize this reference to null, you had to initialize it to 
something else, so you would still get your race condition.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Idan Arye

On Sunday, 19 May 2013 at 17:46:13 UTC, Simen Kjaeraas wrote:
On Sun, 19 May 2013 19:12:15 +0200, Idan Arye 
generic...@gmail.com wrote:


It's a good practice to initialize references(and all other 
types of variables) as soon as possible - and if possible, 
right away in the declaration. If that reference started as 
null, it's safe to assume it was not possible to initialized 
it at declaration, so it was intentionally initialized with 
null(if there was no initialization Java would scream at you).


Now, let's assume that reference was non-nullable. It is safe 
to assume that this change would not remove the obstacle that 
prevented that reference from being initialized right away in 
the declaration - so you still need to initialize it to 
something else - let's call that something `Nil`. Nil is an 
object that tells you that the reference has not yet been 
initialized.


Uhm, no. Nononono. No. This is a complete and utter fallacy. 
What you
have just done is define Nullable!(NonNullable!T). I should not 
have to
explain too closely why this is a bad thing and should not be 
done.


These are the assumptions I'm working with:
 - We can't use a nullable reference
 - We can't initialize the reference upon declaration to it's 
real value.


The first assumption is required because we want to describe how 
the bug scenario deadalnix brought up would look like if 
references were non-nullable. The second assumption is required 
because if we could initialize the reference upon declaration to 
it's real value, we should have just done it in the first place 
and avoid the whole race hazard.


Now, I'm not saying the solution I presented is good - I'm trying 
to show that given those two assumptions, we are forced to use 
this bad solution.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 17:51:36 UTC, Idan Arye wrote:

On Sunday, 19 May 2013 at 17:35:43 UTC, deadalnix wrote:
Idan Arye  Nil proposal make no sens in a statically typed 
language. And you'll find no better kind of null. We have all 
tools we need in D to work around null in library.


That's not the point. The point is that if you couldn't 
initialize this reference to null, you had to initialize it to 
something else, so you would still get your race condition.


Note that it had to be initialized, and my patch to Cayenne was 
simply to reorder that initialization.


The patch itself was ~5lines, and would have impossible to do 
with a nonnullable (except with your Nil stuff, which once again 
don't make any sens in a strongly type language)


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 18:05:03 UTC, Idan Arye wrote:

These are the assumptions I'm working with:
 - We can't use a nullable reference
 - We can't initialize the reference upon declaration to it's 
real value.




If you can't initialize the value, you got to assume when you use 
it that it may not have been initialized and handle that case. 
You need either an Option (where you have to be explicit about 
what you do when the thing is null) or a Maybe (where null is 
ignored and Maybe contaminate every result depending on a maybe 
value).


The first assumption is required because we want to describe 
how the bug scenario deadalnix brought up would look like if 
references were non-nullable. The second assumption is required 
because if we could initialize the reference upon declaration 
to it's real value, we should have just done it in the first 
place and avoid the whole race hazard.




But that is the whole point ! The damn thing should have been 
initialized in the first place to avoid the bug. And this should 
have been caught at compile time with any sane type system.


And this is the exact problem with nullable by default : plenty 
of stuff ends up be null is some weird situation that almost 
never occurs when they are assumed not to be and the program 
crashes. NullPointerException now return 4 millions result on 
google, which is probably around once per java developers.


Now, I'm not saying the solution I presented is good - I'm 
trying to show that given those two assumptions, we are forced 
to use this bad solution.


This solution is complex, do not make any sense in a strongly 
typed language and don't even solve the presented case.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 5:02 AM, Simen Kjaeraas wrote:

By definition? Pointer semantics are what we choose it to mean.

Of course. But which definition is saner:


For many types, it is extremely useful to have some sort of invalid value for 
it. null fills that role nicely for pointers, just as nan does for floating 
point types, and 0xFF does for UTF-8.


There's not anything insane about it. The Nullable type constructor even exists 
in order to provide such an invalid state for types (like int) which normally do 
not have one.


Yes, I do understand there's a role for pointers which cannot hold the invalid 
value.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 10:41 AM, deadalnix wrote:

I have bunch of code that goes like :

auto oldVar = var;
scope(exit) var = oldVar;

This is begging for a RAII solution where I pass var as template parameter but
would require default constructor. This is an actual problem I have right now as
all save/restore are harder and harder to keep in sync for no reason and
generate a lot of boilerplate.

This is a problem I have right now that default constructor would solve, and
this isn't the first time I hit that need.


oldVar isn't being default constructed in your example, nor can I see why you'd 
need a default constructor in order to use RAII for save/restore.




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 18:23:22 UTC, Walter Bright wrote:

On 5/19/2013 5:02 AM, Simen Kjaeraas wrote:
By definition? Pointer semantics are what we choose it to 
mean.

Of course. But which definition is saner:


For many types, it is extremely useful to have some sort of 
invalid value for it. null fills that role nicely for 
pointers, just as nan does for floating point types, and 0xFF 
does for UTF-8.




I don't wanted to bring that up because I thought it would 
confuse people, but yes, 0xFF for char is the exact same problem 
and I argue in the same direction : require explicit 
initialization.


There's not anything insane about it. The Nullable type 
constructor even exists in order to provide such an invalid 
state for types (like int) which normally do not have one.




If something can be null, you MUST do something to handle 
specifically the null case. D completely fail to ensure that.


void buzz(Foo f) {
f.foo(); // Rely in faith. It is invalid and way easier to 
write than the valid code, which is THE recipe for it to spread.

}


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 18:27:08 UTC, Walter Bright wrote:
oldVar isn't being default constructed in your example, nor can 
I see why you'd need a default constructor in order to use RAII 
for save/restore.


I need to save the value at construction and restore at 
destruction. I don't need any runtime parameter at construction.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 10:35 AM, deadalnix wrote:

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

No, the race condition would have stayed.


That is ridiculous. non nullable would have made the bug non existent, and even
without race condition the problem would exists. a reference is null, it
container shared, then set to something else. You can put barriers all over the
place to make that sequentially consistent that it wouldn't change anything and
the bug would still arise.


I agree with Andrei that eliminating null is not going to make a race condition 
into a thread safe one. You've got a serious bug that you may succeed in hiding 
by eliminating the null, but it's still there. From your description, I suspect 
the code is suffering from the double-checked locking bug (which can appear in 
very subtle forms).




You also never provided any convincing solution to the safety hole. We can't
even add check only on some edges cases as D also have values types. The only
solution we are left with that is really safe is to null check every dereference
or give up on @safe.


Please don't make us guess what exactly you mean by this.



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Jacob Carlborg

On 2013-05-19 19:41, deadalnix wrote:


I have bunch of code that goes like :

auto oldVar = var;
scope(exit) var = oldVar;

This is begging for a RAII solution where I pass var as template
parameter but would require default constructor. This is an actual
problem I have right now as all save/restore are harder and harder to
keep in sync for no reason and generate a lot of boilerplate.

This is a problem I have right now that default constructor would solve,
and this isn't the first time I hit that need.


You can do something like this:

void restore (alias value, alias dg) ()
{
auto tmp = value;

scope (exit)
value = tmp;

dg();
}

int a;

void foo () { a = 4 };

void main ()
{
a = 3;
restore!(a, {
foo();
});
}

The syntax isn't that pretty but it should work. I wish D had better 
syntax for this, something like:


restore(a) {
foo();
}

--
/Jacob Carlborg


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Idan Arye

On Sunday, 19 May 2013 at 18:22:16 UTC, deadalnix wrote:

On Sunday, 19 May 2013 at 18:05:03 UTC, Idan Arye wrote:

These are the assumptions I'm working with:
- We can't use a nullable reference
- We can't initialize the reference upon declaration to it's 
real value.




If you can't initialize the value, you got to assume when you 
use it that it may not have been initialized and handle that 
case. You need either an Option (where you have to be explicit 
about what you do when the thing is null) or a Maybe (where 
null is ignored and Maybe contaminate every result depending 
on a maybe value).


I don't see how Option and Maybe would have helped your bug. The 
problem was that somewhere in the code the reference was 
perceived as null while in fact it wasn't - so now it will be 
perceived as `None`, and you will have the same problem.


The first assumption is required because we want to describe 
how the bug scenario deadalnix brought up would look like if 
references were non-nullable. The second assumption is 
required because if we could initialize the reference upon 
declaration to it's real value, we should have just done it in 
the first place and avoid the whole race hazard.




But that is the whole point ! The damn thing should have been 
initialized in the first place to avoid the bug. And this 
should have been caught at compile time with any sane type 
system.


And this is the exact problem with nullable by default : plenty 
of stuff ends up be null is some weird situation that almost 
never occurs when they are assumed not to be and the program 
crashes. NullPointerException now return 4 millions result on 
google, which is probably around once per java developers.


This is not a problem with nullable by default - it is a 
problem with implicit default values. null(or Nil, or None) are 
the only sane default values for reference types - I think you 
would agree that having to construct a new blank object as 
default value for every reference variable would be far worse 
than null...


Now, I'm not saying the solution I presented is good - I'm 
trying to show that given those two assumptions, we are forced 
to use this bad solution.


This solution is complex, do not make any sense in a strongly 
typed language and don't even solve the presented case.


It does not solve the bug - it is something you HAVE to do given 
the assumptions. If the reference is not nullable, and you can't 
set it to it's real value until later in the code, then you have 
to initialize it to some temporary value.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 1:41 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 04:57:15 UTC, Walter Bright wrote:

On 5/18/2013 8:54 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 01:20:31 UTC, Walter Bright wrote:

I understand that. But the rationale you gave for having a default
constructor
was to be able to disable default construction.


RAII or construction based on template parameters.


I know what default constructors are used for in C++. That wasn't what
I asked, though. I asked for compelling rationale.



I have bunch of code that goes like :

auto oldVar = var;
scope(exit) var = oldVar;

This is begging for a RAII solution where I pass var as template
parameter but would require default constructor.


No need for a default constructor. You pass the current value as a 
constructor parameter.


Andrei




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 18:46:31 UTC, Walter Bright wrote:
You also never provided any convincing solution to the safety 
hole. We can't
even add check only on some edges cases as D also have values 
types. The only
solution we are left with that is really safe is to null check 
every dereference

or give up on @safe.


Please don't make us guess what exactly you mean by this.


This isn't new and I discussed that again and again.

When you dereference null, you hit the first plage, which is 
protected on most systems. But if you access an element with 
sufficient offset you bypass all protections provided by the type 
system and you are back in unsafe world.


And no, putting nullcheck on access of field of sufficient offset 
(as propose dby Andrei) isn't enough because we have value types. 
Consider :


S[BIG_NUMBER]* a;
auto s = (*a[SLIGHTLY_BELLOW_CHECK_OFFSET]);
s.fieldAccess; // May not have enough offset to trigget null 
check, but still can be usnafe


See bug reports :
http://d.puremagic.com/issues/show_bug.cgi?id=3677
http://d.puremagic.com/issues/show_bug.cgi?id=5176


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 1:12 PM, Idan Arye wrote:

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

On 5/19/13 9:11 AM, deadalnix wrote:

On Sunday, 19 May 2013 at 13:08:53 UTC, Andrei Alexandrescu wrote:

Sounds like a race problem unrelated to null. With non-null objects
the race would have manifested itself in a different way, perhaps even
more pernicious.



It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of debugging.


No, the race condition would have stayed.


Andrei


I believe this claim requires an explanation:

It's a good practice to initialize references(and all other types of
variables) as soon as possible - and if possible, right away in the
declaration. If that reference started as null, it's safe to assume it
was not possible to initialized it at declaration, so it was
intentionally initialized with null(if there was no initialization Java
would scream at you).

Now, let's assume that reference was non-nullable. It is safe to assume
that this change would not remove the obstacle that prevented that
reference from being initialized right away in the declaration - so you
still need to initialize it to something else - let's call that
something `Nil`. Nil is an object that tells you that the reference has
not yet been initialized.

So, in the original bug the reference could be seen
as null where it was assumed everywhere to be set.. But now we don't
have null - so that piece of code that thought the reference is null
would now think that it is... what? The initialization value? No!
Because we didn't switch from initializing the reference with null to
initializing it with the later initialization value - we couldn't do it.
Instead, we had to use Nil. So now, the reference 'could be seen as Nil
where it was assumed everywhere to be set'...

Now, if you are lucky and your Nil is the better-kind-of-null that is
used in dynamic object oriented languages, you'll get a nil exception -
which is just as good as null exception. But if you are not so lucky,
and you had to declare Nil as a blank object of the type of that
reference, you are going to have logical bug, which is far worse than
exceptions...


So the race would have manifested it just the same, except under the 
name of Nil instead of null.


Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 1:35 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

On 5/19/13 9:11 AM, deadalnix wrote:

It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of debugging.


No, the race condition would have stayed.



That is ridiculous.  non nullable would have made the bug non existent,
and even without race condition the problem would exists. a reference is
null, it container shared, then set to something else. You can put
barriers all over the place to make that sequentially consistent that it
wouldn't change anything and the bug would still arise.


No, your argument is ridiculous. You make a yarn with precious little 
detail that describes for everything everyone knows a textbook race 
condition, essentially ask that you are taking by your word that 
non-null would miraculously solve it, and, to add insult to injury, and 
when we don't buy it, you put the burden of proof on us. This is quite a 
trick, my hat is off to you.



You also never provided any convincing solution to the safety hole.


What's the safety hole? Objects of large static size?


We
can't even add check only on some edges cases as D also have values
types. The only solution we are left with that is really safe is to null
check every dereference or give up on @safe.


How about using NonNull. We won't change the language at this point to 
make non-nullable references by default. Even you acknowledged that 
that's not practical. So now you contradict your own affirmation. What 
exactly do you sustain, and what are you asking for?



I encourage you to look at this :
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare


I read it. I don't buy it. Yeah, it's a point, but it's largely 
exaggerated for dramatic purposes.



Most new languages removed nullable by default, or limited its uses
(scala for instance, allow for null for limited scope).


So what do you realistically think we should do, seeing that we're 
aiming at stability?



I once again want to get attention on the fact that GC change everything
in regard to reference, and that the C++ situation is a bad example.


I don't understand this.


Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Maxim Fomin

On Saturday, 18 May 2013 at 20:39:29 UTC, Walter Bright wrote:

On 5/18/2013 1:22 PM, deadalnix wrote:
Many are, but I think that isn't the point we are discussing 
here.


Removing all holes in @disable this will require the same 
sacrifices at the ends
than default constructor would. For isntance, what should 
happen in this case :


S[] ss;
ss.length = 42;

if S has @disable this ?


Already reported:

http://d.puremagic.com/issues/show_bug.cgi?id=10115


New case, will report it:

struct S
{
   int a;
   @disable this();
   this(int) { a = 1; }
   ~this() { assert(a !is 0); }
   alias a this;
   int opCall() { return a; }
}

void main()
{
   switch (S.init())
   {
  case 0:
 assert(0); //oops
  default:
   }
}

By the way, here is another bug.

I think there is disagreement about @disable reliability and 
usefulness and similar issues (@safe reliability too) due to 
different attitude to  the problem:
- As a language designer I care about whether some feature is 
claimed to solve some problem - and that all, I put it on a slide 
as lang advantage;
- As a programmer who writes medium importance code I care 
whether the feature stops me from making bugs unintentionally. If 
it does, than I consider that the feature works.
- As a programmer who writes critical code I care whether feature 
prevents from problem, even made deliberately, and if it doesn't, 
than the feature isn't reliable. It doesn't mean that it is 
totally useless, but it does mean that its reliability 
commitments are cheap.


Since in system language there is plenty of ways to deliberately 
pass invalid data to the place where some validity assumptions 
were made, @disable is a broken feature.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 3:10 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 18:46:31 UTC, Walter Bright wrote:

You also never provided any convincing solution to the safety hole.
We can't
even add check only on some edges cases as D also have values types.
The only
solution we are left with that is really safe is to null check every
dereference
or give up on @safe.


Please don't make us guess what exactly you mean by this.


This isn't new and I discussed that again and again.

When you dereference null, you hit the first plage, which is protected
on most systems. But if you access an element with sufficient offset you
bypass all protections provided by the type system and you are back in
unsafe world.


Oh, the good old object of sufficient size. We know how to fix that.


And no, putting nullcheck on access of field of sufficient offset (as
propose dby Andrei) isn't enough because we have value types. Consider :

S[BIG_NUMBER]* a;
auto s = (*a[SLIGHTLY_BELLOW_CHECK_OFFSET]);
s.fieldAccess; // May not have enough offset to trigget null check, but
still can be usnafe

See bug reports :
http://d.puremagic.com/issues/show_bug.cgi?id=3677
http://d.puremagic.com/issues/show_bug.cgi?id=5176


All of the above are variations on the sufficiently large object theme.

Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Minas Mina

On Sunday, 19 May 2013 at 18:30:09 UTC, deadalnix wrote:

void buzz(Foo f) {
f.foo(); // Rely in faith. It is invalid and way easier to 
write than the valid code, which is THE recipe for it to spread.

}


Shouldn't this throw a NullPointerSomething?


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 19:10:28 UTC, Andrei Alexandrescu wrote:
No, your argument is ridiculous. You make a yarn with precious 
little detail that describes for everything everyone knows a 
textbook race condition, essentially ask that you are taking by 
your word that non-null would miraculously solve it, and, to 
add insult to injury, and when we don't buy it, you put the 
burden of proof on us. This is quite a trick, my hat is off to 
you.




I described a very usual null bug : something is set to null, 
then to a specific value. It is assumed not to be null. In a 
specific case it is null and everything explode.


The concurrent context here made it especially hard to debug, but 
isn't the cause of the bug.


Additionally, if you don't have enough information to understand 
what I'm saying, you are perfectly allowed to ask for additional 
details This isn't a shame.


You also never provided any convincing solution to the safety 
hole.


What's the safety hole? Objects of large static size?



Limiting object size isn't going to cut it. Or must be super 
restrictive (the protection is 4kb on some systems).



We
can't even add check only on some edges cases as D also have 
values
types. The only solution we are left with that is really safe 
is to null

check every dereference or give up on @safe.


How about using NonNull. We won't change the language at this 
point to make non-nullable references by default. Even you 
acknowledged that that's not practical. So now you contradict 
your own affirmation. What exactly do you sustain, and what are 
you asking for?




1/ NonNull do not work.
2/ It isn't because it is too late to solve a problem that it 
magically isn't a problem anymore.


Most new languages removed nullable by default, or limited its 
uses

(scala for instance, allow for null for limited scope).


So what do you realistically think we should do, seeing that 
we're aiming at stability?




Acknowledge it was a mistake and move on. Use the analysis that 
need to be done to track down @disable this issue to warn about 
uninitialized null stuffs.


I once again want to get attention on the fact that GC change 
everything
in regard to reference, and that the C++ situation is a bad 
example.


I don't understand this.



I C or C++ you are doomed to manage reference as you need to for 
memory management purpose. In garbage collected languages, you 
ends up with way more unmanaged references, because the GC take 
care of them. Doing so you multiply the surface area where null 
bug can strike.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 19:15:47 UTC, Andrei Alexandrescu wrote:
Oh, the good old object of sufficient size. We know how to 
fix that.


And no, putting nullcheck on access of field of sufficient 
offset (as
propose dby Andrei) isn't enough because we have value types. 
Consider :


S[BIG_NUMBER]* a;
auto s = (*a[SLIGHTLY_BELLOW_CHECK_OFFSET]);
s.fieldAccess; // May not have enough offset to trigget null 
check, but

still can be usnafe

See bug reports :
http://d.puremagic.com/issues/show_bug.cgi?id=3677
http://d.puremagic.com/issues/show_bug.cgi?id=5176


All of the above are variations on the sufficiently large 
object theme.


Andrei


The code above never access a field with a sufficient offset to 
trigger sufficiently large runtime check. Obviously, in the 
presented code the bug is trivial, but if the dereferences occurs 
across several functions, this is doomed to fail.


The solutions are : prevent any conglomerate of value type to be 
bigger than 4kb (the protection on OSX is 4kb) or put a null 
check on every dereference in @safe code.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 12:13 PM, Maxim Fomin wrote:

Since in system language there is plenty of ways to deliberately pass invalid
data to the place where some validity assumptions were made, @disable is a
broken feature.


Please report all such holes to bugzilla.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 12:31 PM, Minas Mina wrote:

On Sunday, 19 May 2013 at 18:30:09 UTC, deadalnix wrote:

void buzz(Foo f) {
f.foo(); // Rely in faith. It is invalid and way easier to write than the
valid code, which is THE recipe for it to spread.
}


Shouldn't this throw a NullPointerSomething?


It throws a seg fault at runtime. It *is* checked for by the hardware.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/19/2013 09:10 PM, Andrei Alexandrescu wrote:

On 5/19/13 1:35 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 13:13:07 UTC, Andrei Alexandrescu wrote:

On 5/19/13 9:11 AM, deadalnix wrote:

It is both a race condition and a null problem.


No, it's just a race condition.


And having non nullable
type would have been a compile time error instead of days of debugging.


No, the race condition would have stayed.



That is ridiculous.  non nullable would have made the bug non existent,
and even without race condition the problem would exists. a reference is
null, it container shared, then set to something else. You can put
barriers all over the place to make that sequentially consistent that it
wouldn't change anything and the bug would still arise.


No, your argument is ridiculous. You make a yarn with precious little
detail that describes for everything everyone knows a textbook race
condition, essentially ask that you are taking by your word that
non-null would miraculously solve it, and, to add insult to injury, and
when we don't buy it, you put the burden of proof on us. This is quite a
trick, my hat is off to you.
...


It is easy to buy that the buggy code would have been rejected by a 
stronger type system whereas the fixed code would have passed type 
checking. Especially given that it manifested itself as a NPE, which 
would not even exist.




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 3:41 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 19:15:47 UTC, Andrei Alexandrescu wrote:

Oh, the good old object of sufficient size. We know how to fix that.


And no, putting nullcheck on access of field of sufficient offset (as
propose dby Andrei) isn't enough because we have value types. Consider :

S[BIG_NUMBER]* a;
auto s = (*a[SLIGHTLY_BELLOW_CHECK_OFFSET]);
s.fieldAccess; // May not have enough offset to trigget null check, but
still can be usnafe

See bug reports :
http://d.puremagic.com/issues/show_bug.cgi?id=3677
http://d.puremagic.com/issues/show_bug.cgi?id=5176


All of the above are variations on the sufficiently large object theme.

Andrei


The code above never access a field with a sufficient offset to trigger
sufficiently large runtime check.


It does, when the pointer to the large static array is dereferenced.

Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/19/2013 09:42 PM, Walter Bright wrote:

On 5/19/2013 12:31 PM, Minas Mina wrote:

On Sunday, 19 May 2013 at 18:30:09 UTC, deadalnix wrote:

void buzz(Foo f) {
f.foo(); // Rely in faith. It is invalid and way easier to write
than the
valid code, which is THE recipe for it to spread.
}


Shouldn't this throw a NullPointerSomething?


It throws a seg fault at runtime. It *is* checked for by the hardware.


Yes, but this code looks like it calls method 'foo', which is probably 
its intention. Hence it is buggy.


D's current answer is the following:

void buzz(Foo f)in{assert(!!f);}body{
f.foo();
}



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 11:37 AM, deadalnix wrote:

On Sunday, 19 May 2013 at 18:27:08 UTC, Walter Bright wrote:

oldVar isn't being default constructed in your example, nor can I see why
you'd need a default constructor in order to use RAII for save/restore.


I need to save the value at construction and restore at destruction. I don't
need any runtime parameter at construction.


The saved value is initialized with the value to be saved. This is not default 
construction.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/19/2013 09:10 PM, Andrei Alexandrescu wrote:

I encourage you to look at this :
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



I read it. I don't buy it. Yeah, it's a point, but it's largely
exaggerated for dramatic purposes.


(It is a talk.)


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 3:36 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 19:10:28 UTC, Andrei Alexandrescu wrote:

No, your argument is ridiculous. You make a yarn with precious little
detail that describes for everything everyone knows a textbook race
condition, essentially ask that you are taking by your word that
non-null would miraculously solve it, and, to add insult to injury,
and when we don't buy it, you put the burden of proof on us. This is
quite a trick, my hat is off to you.



I described a very usual null bug : something is set to null, then to a
specific value. It is assumed not to be null. In a specific case it is
null and everything explode.

The concurrent context here made it especially hard to debug, but isn't
the cause of the bug.

Additionally, if you don't have enough information to understand what
I'm saying, you are perfectly allowed to ask for additional details This
isn't a shame.


Your argument has been destroyed so no need to ask details about it. 
Replace null with invalid state and it's the same race in any 
system. Let's move on.



What's the safety hole? Objects of large static size?



Limiting object size isn't going to cut it. Or must be super restrictive
(the protection is 4kb on some systems).


Well you got to do what you got to do. Field accesses for objects larger 
than 4KB would have to be checked in @safe code.



We
can't even add check only on some edges cases as D also have values
types. The only solution we are left with that is really safe is to null
check every dereference or give up on @safe.


How about using NonNull. We won't change the language at this point to
make non-nullable references by default. Even you acknowledged that
that's not practical. So now you contradict your own affirmation. What
exactly do you sustain, and what are you asking for?



1/ NonNull do not work.


You made the argument that although it does work, people will not use it 
because it's not the default. That's not quite does not work. This 
also ruins your point because if people don't find it worth writing 
NonNull!T instead of T, it means non-null doesn't buy them anything 
worthwhile.



2/ It isn't because it is too late to solve a problem that it magically
isn't a problem anymore.


You are blowing it out of proportion. Null references are hardly even on 
the radar of the bug classes I'm encountering in the style of 
programming of the three groups I worked in at Facebook, and also my 
previous employers. People I meet at conferences and consulting gigs 
never mention null references as a real problem, although I very often 
ask about problems. I find it difficult to agree with you just to be nice.



Most new languages removed nullable by default, or limited its uses
(scala for instance, allow for null for limited scope).


So what do you realistically think we should do, seeing that we're
aiming at stability?



Acknowledge it was a mistake and move on.


I'd give it more thought if we designed D from scratch. I think it's 
safe to move on. At any rate, I'd love if we got NonNull working nicely 
so we accumulate more experience with it.



Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Maxim Fomin

On Sunday, 19 May 2013 at 19:42:59 UTC, Walter Bright wrote:

On 5/19/2013 12:31 PM, Minas Mina wrote:

On Sunday, 19 May 2013 at 18:30:09 UTC, deadalnix wrote:

void buzz(Foo f) {
   f.foo(); // Rely in faith. It is invalid and way easier to 
write than the

valid code, which is THE recipe for it to spread.
}


Shouldn't this throw a NullPointerSomething?


It throws a seg fault at runtime. It *is* checked for by the 
hardware.


I think there is difference between catching exception and saving
data which you have typed for some period and letting harware
check the exception for you meanwile loosing your work.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 12:10 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 18:46:31 UTC, Walter Bright wrote:

You also never provided any convincing solution to the safety hole. We can't
even add check only on some edges cases as D also have values types. The only
solution we are left with that is really safe is to null check every dereference
or give up on @safe.


Please don't make us guess what exactly you mean by this.


This isn't new and I discussed that again and again.

When you dereference null, you hit the first plage, which is protected on most
systems. But if you access an element with sufficient offset you bypass all
protections provided by the type system and you are back in unsafe world.



And we've replied to this before. But when you say give up on @safe, that 
implies a far more serious issue, so I want to make sure what you're talking about.


I agree that we need to deal with the issue. But on a practical note, if we 
solve 99% of the @safe issues, and fail at 1%, that doesn't mean there is no 
value to @safe and we should give up on it.




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 3:58 PM, Timon Gehr wrote:

On 05/19/2013 09:10 PM, Andrei Alexandrescu wrote:

I encourage you to look at this :
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare




I read it. I don't buy it. Yeah, it's a point, but it's largely
exaggerated for dramatic purposes.


(It is a talk.)


(I read a transcript.)

Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 4:05 PM, Walter Bright wrote:

On 5/19/2013 12:10 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 18:46:31 UTC, Walter Bright wrote:

You also never provided any convincing solution to the safety hole.
We can't
even add check only on some edges cases as D also have values types.
The only
solution we are left with that is really safe is to null check every
dereference
or give up on @safe.


Please don't make us guess what exactly you mean by this.


This isn't new and I discussed that again and again.

When you dereference null, you hit the first plage, which is protected
on most
systems. But if you access an element with sufficient offset you
bypass all
protections provided by the type system and you are back in unsafe world.



And we've replied to this before. But when you say give up on @safe,
that implies a far more serious issue, so I want to make sure what
you're talking about.

I agree that we need to deal with the issue. But on a practical note, if
we solve 99% of the @safe issues, and fail at 1%, that doesn't mean
there is no value to @safe and we should give up on it.


Almost safe == almost pregnant. @safe must be 100% safe.

Andrei




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Mr. Anonymous

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:
Well you got to do what you got to do. Field accesses for 
objects larger than 4KB would have to be checked in @safe code.


Isn't the solution as easy as doing:
OR PTR:[address], 0
the same way it's done for the stack?

The offset it known at compile time in most cases, so the command 
would be required only if both:

* The object is larger than target OS' guard page size.
* The position is greater than target OS' guard page size, OR is 
unknown at compile time.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 12:36 PM, deadalnix wrote:

I C or C++ you are doomed to manage reference as you need to for memory
management purpose. In garbage collected languages, you ends up with way more
unmanaged references, because the GC take care of them. Doing so you multiply
the surface area where null bug can strike.


I still don't see the connection.

I've had many more null pointer bugs in non-gc code than in gc code, but I 
attribute that to my being a better programmer in gc code because I did that 
later and was more aware of issues.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Peter Alexander

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:
You are blowing it out of proportion. Null references are 
hardly even on the radar of the bug classes I'm encountering in 
the style of programming of the three groups I worked in at 
Facebook, and also my previous employers. People I meet at 
conferences and consulting gigs never mention null references 
as a real problem, although I very often ask about problems. I 
find it difficult to agree with you just to be nice.


Just because people don't mention them as a problem doesn't mean 
it isn't a problem.


For what it's worth, null pointers are a real problem in the code 
I work on (games). I don't know exactly what you work on, but I 
find that they are more of a problem in highly stateful, 
interactive applications. Things like generic libraries, utility 
programs, compilers, etc. probably won't see the same problems 
because they aren't very stateful or interactive.


In my experience, null pointers are easy to fix, but the risk of 
them causes people to litter their code with if (ptr) tests, 
often with poor handling of the failure case, which can cause 
subtle bugs (no crash, but unintended code path).


Just my 2c.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 1:06 PM, Andrei Alexandrescu wrote:

On 5/19/13 3:58 PM, Timon Gehr wrote:

(It is a talk.)


(I read a transcript.)


I wish more talks had transcripts available. I can read an hour talk 
presentation in 5 minutes.




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 1:08 PM, Mr. Anonymous wrote:

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:

Well you got to do what you got to do. Field accesses for objects larger than
4KB would have to be checked in @safe code.


Isn't the solution as easy as doing:
OR PTR:[address], 0
the same way it's done for the stack?

The offset it known at compile time in most cases, so the command would be
required only if both:
* The object is larger than target OS' guard page size.
* The position is greater than target OS' guard page size, OR is unknown at
compile time.


Not a bad idea.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 1:03 PM, Maxim Fomin wrote:

I think there is difference between catching exception and saving
data which you have typed for some period and letting harware
check the exception for you meanwile loosing your work.


You can catch seg faults. It's easier on Windows, but it's doable on Linux.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 11:22 AM, deadalnix wrote:

The damn thing should have been initialized in the
first place to avoid the bug.


Sounds like you have the double-checked locking bug. Using a different value to 
initialize it won't fix it.


If you have a global value accessible from multiple threads, you must use 
synchronization. There is no way around that. If you use some other global state 
to check for initialization in order to avoid synchronization, you have the 
double checked locking bug. Yes, you do.





Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 2:02 PM, Walter Bright wrote:

If you have a global value accessible from multiple threads, you must use
synchronization. There is no way around that. If you use some other global state
to check for initialization in order to avoid synchronization, you have the
double checked locking bug. Yes, you do.



BTW, a few years ago, I presented my clever solution to the double checked 
locking bug to Scott Meyers. I was very proud of it. Scott handed me my @ss (in 
a nice way), but I got my comeuppance.


It reminded me of the hours I spent in high school determined to show that I 
could trisect an angle with a compass and a straightedge. There was always some 
tiny flaw :-)




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 4:30 PM, Peter Alexander wrote:

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:

You are blowing it out of proportion. Null references are hardly even
on the radar of the bug classes I'm encountering in the style of
programming of the three groups I worked in at Facebook, and also my
previous employers. People I meet at conferences and consulting gigs
never mention null references as a real problem, although I very often
ask about problems. I find it difficult to agree with you just to be
nice.


Just because people don't mention them as a problem doesn't mean it
isn't a problem.

For what it's worth, null pointers are a real problem in the code I work
on (games). I don't know exactly what you work on, but I find that they
are more of a problem in highly stateful, interactive applications.
Things like generic libraries, utility programs, compilers, etc.
probably won't see the same problems because they aren't very stateful
or interactive.

In my experience, null pointers are easy to fix, but the risk of them
causes people to litter their code with if (ptr) tests, often with poor
handling of the failure case, which can cause subtle bugs (no crash, but
unintended code path).

Just my 2c.


OK, this is sensible. One question - would you be willing to type 
symbols as NullType!T instead of T to avoid these issues?


Thanks,

Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:

On 5/19/13 3:36 PM, deadalnix wrote:
On Sunday, 19 May 2013 at 19:10:28 UTC, Andrei Alexandrescu 
wrote:
No, your argument is ridiculous. You make a yarn with 
precious little
detail that describes for everything everyone knows a 
textbook race
condition, essentially ask that you are taking by your word 
that
non-null would miraculously solve it, and, to add insult to 
injury,
and when we don't buy it, you put the burden of proof on us. 
This is

quite a trick, my hat is off to you.



I described a very usual null bug : something is set to null, 
then to a
specific value. It is assumed not to be null. In a specific 
case it is

null and everything explode.

The concurrent context here made it especially hard to debug, 
but isn't

the cause of the bug.

Additionally, if you don't have enough information to 
understand what
I'm saying, you are perfectly allowed to ask for additional 
details This

isn't a shame.


Your argument has been destroyed so no need to ask details 
about it. Replace null with invalid state and it's the same 
race in any system. Let's move on.




I don't want t to understand because I know I'm right. The fact 
you solved that issue and I didn't is irrelevant, I know better.


You are blowing it out of proportion. Null references are 
hardly even on the radar of the bug classes I'm encountering in 
the style of programming of the three groups I worked in at 
Facebook, and also my previous employers. People I meet at 
conferences and consulting gigs never mention null references 
as a real problem, although I very often ask about problems. I 
find it difficult to agree with you just to be nice.




Hiphop type annotations are non null by default. Just saying.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 21:02:57 UTC, Walter Bright wrote:

On 5/19/2013 11:22 AM, deadalnix wrote:

The damn thing should have been initialized in the
first place to avoid the bug.


Sounds like you have the double-checked locking bug. Using a 
different value to initialize it won't fix it.




No it sound like initalizing something to null, then initialize 
it properly, assume all over the place that it is initialized to 
something else, and in some rare code path it blows up.


The fact that this occurs in a multithreaded environment made it 
super hard to debug, but the whole thing was properly 
synchronized.


Don't assume that I do not understand what the problem with 
double check locking is : 
http://d.puremagic.com/issues/show_bug.cgi?id=6607


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 20:30:28 UTC, Peter Alexander wrote:
On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu 
wrote:
You are blowing it out of proportion. Null references are 
hardly even on the radar of the bug classes I'm encountering 
in the style of programming of the three groups I worked in at 
Facebook, and also my previous employers. People I meet at 
conferences and consulting gigs never mention null references 
as a real problem, although I very often ask about problems. I 
find it difficult to agree with you just to be nice.


Just because people don't mention them as a problem doesn't 
mean it isn't a problem.


For what it's worth, null pointers are a real problem in the 
code I work on (games). I don't know exactly what you work on, 
but I find that they are more of a problem in highly stateful, 
interactive applications. Things like generic libraries, 
utility programs, compilers, etc. probably won't see the same 
problems because they aren't very stateful or interactive.


In my experience, null pointers are easy to fix, but the risk 
of them causes people to litter their code with if (ptr) tests, 
often with poor handling of the failure case, which can cause 
subtle bugs (no crash, but unintended code path).


Just my 2c.


Exactly !

Most of time null issue are easy to solve and is just the kind of 
crap that slow you down, and once in a while this ends up being 
an horrible mess.


It is also true that rare path are often badly tested (and 
sometime you have no clue if the thing can be null or not, so you 
don't even know how to test it). Same argument Walter like to 
make about very rare failure cases apply here.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread w0rp

On Sunday, 19 May 2013 at 21:36:17 UTC, Andrei Alexandrescu wrote:

On 5/19/13 4:30 PM, Peter Alexander wrot
OK, this is sensible. One question - would you be willing to 
type symbols as NullType!T instead of T to avoid these issues?


Thanks,

Andrei


Trying to come up with some once-and-for-all safe way to deal 
with null in languages which allow null references by default is 
something I wonder about now and then. This is due to my desire 
to adopt nice patterns for making my time spent working with a 
language safer and easier.


Option/Maybe I think only really works when the language has 
references as non-null by default. Otherwise, you're writing 
verbose code for Option/Maybe and lies the rest of the time. (I'm 
looking at Scala.) For D, I decided that my way to do it, to be 
applied almost all of the time, is to write contracts.


void func(Klass value) in {
assert(value !is null);
} body {
}

This stops null from being passed through too many functions, so 
that alleviates a lot of problems. I think contract programming 
is a good solution for this, and it applies more generally to 
other kinds of invalid values. This can include values other than 
the default values.




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 5:11 PM, Walter Bright wrote:

It reminded me of the hours I spent in high school determined to show
that I could trisect an angle with a compass and a straightedge. There
was always some tiny flaw :-)


Yah, sounds familiar. Did you prove the parallel postulate, too?

Andrei



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 5:56 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 21:02:57 UTC, Walter Bright wrote:

On 5/19/2013 11:22 AM, deadalnix wrote:

The damn thing should have been initialized in the
first place to avoid the bug.


Sounds like you have the double-checked locking bug. Using a different
value to initialize it won't fix it.



No it sound like initalizing something to null, then initialize it
properly, assume all over the place that it is initialized to something
else, and in some rare code path it blows up.

The fact that this occurs in a multithreaded environment made it super
hard to debug, but the whole thing was properly synchronized.


How was there a bug if everything was properly synchronized? You either 
describe the matter with sufficient detail, or acknowledge the 
destruction of your anecdote. This is going nowhere.


Andrei




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 5:52 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 20:03:24 UTC, Andrei Alexandrescu wrote:

On 5/19/13 3:36 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 19:10:28 UTC, Andrei Alexandrescu wrote:

No, your argument is ridiculous. You make a yarn with precious little
detail that describes for everything everyone knows a textbook race
condition, essentially ask that you are taking by your word that
non-null would miraculously solve it, and, to add insult to injury,
and when we don't buy it, you put the burden of proof on us. This is
quite a trick, my hat is off to you.



I described a very usual null bug : something is set to null, then to a
specific value. It is assumed not to be null. In a specific case it is
null and everything explode.

The concurrent context here made it especially hard to debug, but isn't
the cause of the bug.

Additionally, if you don't have enough information to understand what
I'm saying, you are perfectly allowed to ask for additional details This
isn't a shame.


Your argument has been destroyed so no need to ask details about it.
Replace null with invalid state and it's the same race in any
system. Let's move on.



I don't want t to understand because I know I'm right. The fact you
solved that issue and I didn't is irrelevant, I know better.


Nobody knows what the issue is. It's all unstated assumptions leading to 
vague claims. You have been challenged to explain it so as to count as 
an anecdote in favor of non-null pointers - which it may as well be! -, 
and failed to raise to it.


Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu wrote:
How was there a bug if everything was properly synchronized? 
You either describe the matter with sufficient detail, or 
acknowledge the destruction of your anecdote. This is going 
nowhere.




I explained over and over. A field is initialized to null, while 
the object lock is owned, and later to its value, while it is 
locked. In the meantime, another thread access the object, owning 
the lock, assuming the field is always initialized.


The exact same problem arise quite often in the single threaded 
world : a reference is set to null, the dev try to be clever when 
initializing it, in a rare case it isn't, and everything blows up 
when it occurs.


It is simply easier to reproduce when things are single threaded, 
and are often quickly debugged in that case.


As explained, the multithreaded environment makes it super hard 
to debug, not the primary cause of the issue. The simply 
consistent in moving the initialization where it was set to null 
in the first place.


It is an instance of the very classic something may be null and 
code use it assuming it is never null.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 3:30 PM, Andrei Alexandrescu wrote:

On 5/19/13 5:11 PM, Walter Bright wrote:

It reminded me of the hours I spent in high school determined to show
that I could trisect an angle with a compass and a straightedge. There
was always some tiny flaw :-)


Yah, sounds familiar. Did you prove the parallel postulate, too?


No. That one was intuitively obvious!



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 4:06 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu wrote:

How was there a bug if everything was properly synchronized? You either
describe the matter with sufficient detail, or acknowledge the destruction of
your anecdote. This is going nowhere.



I explained over and over. A field is initialized to null, while the object lock
is owned, and later to its value, while it is locked. In the meantime, another
thread access the object, owning the lock, assuming the field is always
initialized.


so, you have:
==
Thread A Thread B

lock
   p = null
unlock
 lock
*p = ...
 unlock
lock
   p = new ...
unlock
==
Although you are using locks, it still isn't properly synchronized. Changing the 
p=null to p=someothernonnullvalue will not fix it.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Andrei Alexandrescu

On 5/19/13 7:06 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu wrote:

How was there a bug if everything was properly synchronized? You
either describe the matter with sufficient detail, or acknowledge the
destruction of your anecdote. This is going nowhere.



I explained over and over. A field is initialized to null, while the
object lock is owned, and later to its value, while it is locked. In the
meantime, another thread access the object, owning the lock, assuming
the field is always initialized.


How does another thread thread accesses the object owning the lock 
when the assignment occurs under lock?


How would non-null fix this? Would the object have type Maybe?


Andrei


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Jonathan M Davis
On Sunday, May 19, 2013 09:08:53 Andrei Alexandrescu wrote:
 Anyhow, this discussion should have finality. We could go on forever
 arguing the usefulness or lack thereof of non-nullable references. They
 didn't catch up in some languages and did in some. My personal opinion
 is nice to have, but not greatly compelling.
 
 It's reasonable to assume no major language changes will accommodate
 non-null references, so the next best thing would be to focus on a
 library solution. As Walter said, a library solution has the perk of
 allowing other interesting restricted types.

Wow, this thread really expanded since I looked at it last night. Yeah, I 
thought that it was clear that NonNullable or NotNull or whatever we want to 
call it was going to go in std.typecons and that that was going to be our 
solution to non-nullable references. This is one of those discussions that I 
should probably just stay out of, since it never seems to go anywhere useful. 
We've already decided on a solution. We just haven't gotten it into the 
standard library yet.

- Jonathan M Davis


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 3:04 PM, deadalnix wrote:

Same argument Walter like to make about very rare failure cases apply here.



1. rare as in programmers rarely create such a bug

2. rare as in being rare for an existing bug to show itself

I was referring to (1), while you are referring to (2).


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Idan Arye

On Sunday, 19 May 2013 at 23:07:00 UTC, deadalnix wrote:
On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu 
wrote:
How was there a bug if everything was properly synchronized? 
You either describe the matter with sufficient detail, or 
acknowledge the destruction of your anecdote. This is going 
nowhere.




I explained over and over. A field is initialized to null, 
while the object lock is owned, and later to its value, while 
it is locked. In the meantime, another thread access the 
object, owning the lock, assuming the field is always 
initialized.


The exact same problem arise quite often in the single threaded 
world : a reference is set to null, the dev try to be clever 
when initializing it, in a rare case it isn't, and everything 
blows up when it occurs.


It is simply easier to reproduce when things are single 
threaded, and are often quickly debugged in that case.


As explained, the multithreaded environment makes it super hard 
to debug, not the primary cause of the issue. The simply 
consistent in moving the initialization where it was set to 
null in the first place.


It is an instance of the very classic something may be null and 
code use it assuming it is never null.


So this is not a problem of nullableness - rather this is a 
problem of mutability.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread John Colvin

On Sunday, 19 May 2013 at 20:45:39 UTC, Walter Bright wrote:

On 5/19/2013 1:03 PM, Maxim Fomin wrote:
I think there is difference between catching exception and 
saving

data which you have typed for some period and letting harware
check the exception for you meanwile loosing your work.


You can catch seg faults. It's easier on Windows, but it's 
doable on Linux.


What's the rational for not doing this by default in D? Wouldn't 
a MemoryAccessError or similar be better than crashing out with 
SIGSEGV ? I have no idea about the consequences of this (other 
than tempting people to catch a segfault when they shouldn't, 
which is pretty much always).


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Sunday, 19 May 2013 at 23:29:53 UTC, Walter Bright wrote:

On 5/19/2013 4:06 PM, deadalnix wrote:
On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu 
wrote:
How was there a bug if everything was properly synchronized? 
You either
describe the matter with sufficient detail, or acknowledge 
the destruction of

your anecdote. This is going nowhere.



I explained over and over. A field is initialized to null, 
while the object lock
is owned, and later to its value, while it is locked. In the 
meantime, another
thread access the object, owning the lock, assuming the field 
is always

initialized.


so, you have:
==
Thread A Thread B

lock
   p = null


Here p = null is implicit, this is part of the fun. The 
initialisation is still properly synchronized.



unlock
 lock
*p = ...


It was in java, so more somethign like p.foo(); But yes.


 unlock
lock
   p = new ...
unlock
==
Although you are using locks, it still isn't properly 
synchronized. Changing the p=null to p=someothernonnullvalue 
will not fix it.


No race condition exists in that program. The error lie in 
improper initialization of p in the first place, which should 
never has been null. The example looks dumb as this, you have to 
imagine the pattern hidden in thousands of LOC.


The code is bugguy, but you'll find no undefined threading 
effect? What happen is perfectly defined here and no thread 
access shared data without owning the lock.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Monday, 20 May 2013 at 00:23:59 UTC, John Colvin wrote:

On Sunday, 19 May 2013 at 20:45:39 UTC, Walter Bright wrote:

On 5/19/2013 1:03 PM, Maxim Fomin wrote:
I think there is difference between catching exception and 
saving

data which you have typed for some period and letting harware
check the exception for you meanwile loosing your work.


You can catch seg faults. It's easier on Windows, but it's 
doable on Linux.


What's the rational for not doing this by default in D? 
Wouldn't a MemoryAccessError or similar be better than crashing 
out with SIGSEGV ? I have no idea about the consequences of 
this (other than tempting people to catch a segfault when they 
shouldn't, which is pretty much always).


https://github.com/D-Programming-Language/druntime/blob/master/src/etc/linux/memoryerror.d

Still you can have weird effect when the code above throw in a 
middle of a C routine or something. As C don't know about D 
exception, it is definitively something to be aware of.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Monday, 20 May 2013 at 00:09:23 UTC, Walter Bright wrote:

On 5/19/2013 3:04 PM, deadalnix wrote:
Same argument Walter like to make about very rare failure 
cases apply here.



1. rare as in programmers rarely create such a bug

2. rare as in being rare for an existing bug to show itself

I was referring to (1), while you are referring to (2).


When you talk about UNIX utilities not handling properly a full 
filesystem for instance, you are referring to 1.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Steven Schveighoffer
On Sun, 19 May 2013 16:03:24 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



On 5/19/13 3:36 PM, deadalnix wrote:

I described a very usual null bug : something is set to null, then to a
specific value. It is assumed not to be null. In a specific case it is
null and everything explode.

The concurrent context here made it especially hard to debug, but isn't
the cause of the bug.

Additionally, if you don't have enough information to understand what
I'm saying, you are perfectly allowed to ask for additional details This
isn't a shame.


Your argument has been destroyed so no need to ask details about it.  
Replace null with invalid state and it's the same race in any  
system. Let's move on.


I just wanted to chime in with this understanding of the bug that I am  
reading from deadalnix's descriptions:


SomeObj obj;
shareTheObj(obj); // goes to other threads
obj = new SomeObj; // initialize obj

This is likely simpler than the actual problem, but I think this is the  
gist of it.


A Non-Nullable solution WOULD solve the race:

SomeObj obj; // Compiler: nope, can't do that, must initialize it.

Now, with an invalid state not available like null, is the developer  
more likely to go through the trouble of building an invalid state for  
obj, in order to keep the racy behavior?  No.  He's just going to move the  
initialization:


SomeObj obj = new SomeObj;
shareTheObj(obj);

In essence the point of the anecdote is that a Non-Nullable reference  
would have PROMOTED avoiding the race condition -- it would have been  
harder to keep the racy behavior.


I'm not saying that I think we need NN references as a compiler-supported  
type, or that it needs to be the default, or that NN references ALWAYS  
solve race conditions.  I'm just pointing out what I see is an obvious  
misinterpretation of the underlying story.


-Steve


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/20/2013 01:39 AM, Andrei Alexandrescu wrote:

On 5/19/13 7:06 PM, deadalnix wrote:

On Sunday, 19 May 2013 at 22:32:58 UTC, Andrei Alexandrescu wrote:

How was there a bug if everything was properly synchronized? You
either describe the matter with sufficient detail, or acknowledge the
destruction of your anecdote. This is going nowhere.



I explained over and over. A field is initialized to null, while the
object lock is owned, and later to its value, while it is locked. In the
meantime, another thread access the object, owning the lock, assuming
the field is always initialized.


How does another thread thread accesses the object owning the lock
when the assignment occurs under lock?



lock{ initialize to null. }
lock{ in the meantime assume correctly initialized. }
lock{ initialize correctly. }

This is nothing new. I think he has been pretty clear about what the 
issue is from the beginning.



How would non-null fix this? Would the object have type Maybe?



This is one possibility. In this case, the type system would have 
prevented the null dereference.
In the other case, the type system would have caught the invalid 
initialization.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Timon Gehr

On 05/20/2013 02:33 AM, deadalnix wrote:

On Monday, 20 May 2013 at 00:09:23 UTC, Walter Bright wrote:

On 5/19/2013 3:04 PM, deadalnix wrote:

Same argument Walter like to make about very rare failure cases apply
here.



1. rare as in programmers rarely create such a bug

2. rare as in being rare for an existing bug to show itself

I was referring to (1), while you are referring to (2).


When you talk about UNIX utilities not handling properly a full
filesystem for instance, you are referring to 1.


You mean 2.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Kenji Hara
Unfortunately this is currently not a bug.
T.init provides default initialized object image, and it *does not*
provide default constructed object. The difference is important.

That is already documented in lanugage reference.
http://dlang.org/property#init

 Note: .init produces a default initialized object, not default
constructed. That means using .init is sometimes incorrect.
 1. If T is a nested struct, the context pointer in T.init is null.
 2. If T is a struct which has @disable this();, T.init might return a
logically incorrect object.

Kenji Hara

2013/5/20 Maxim Fomin ma...@maxim-fomin.ru

 On Saturday, 18 May 2013 at 20:39:29 UTC, Walter Bright wrote:

 On 5/18/2013 1:22 PM, deadalnix wrote:

 Many are, but I think that isn't the point we are discussing here.

 Removing all holes in @disable this will require the same sacrifices at
 the ends
 than default constructor would. For isntance, what should happen in this
 case :

 S[] ss;
 ss.length = 42;

 if S has @disable this ?


 Already reported:

 http://d.puremagic.com/issues/**show_bug.cgi?id=10115http://d.puremagic.com/issues/show_bug.cgi?id=10115


 New case, will report it:


 struct S
 {
int a;
@disable this();
this(int) { a = 1; }
~this() { assert(a !is 0); }
alias a this;
int opCall() { return a; }
 }

 void main()
 {
switch (S.init())
{
   case 0:
  assert(0); //oops
   default:
}
 }

 By the way, here is another bug.

 I think there is disagreement about @disable reliability and usefulness
 and similar issues (@safe reliability too) due to different attitude to
  the problem:
 - As a language designer I care about whether some feature is claimed to
 solve some problem - and that all, I put it on a slide as lang advantage;
 - As a programmer who writes medium importance code I care whether the
 feature stops me from making bugs unintentionally. If it does, than I
 consider that the feature works.
 - As a programmer who writes critical code I care whether feature prevents
 from problem, even made deliberately, and if it doesn't, than the feature
 isn't reliable. It doesn't mean that it is totally useless, but it does
 mean that its reliability commitments are cheap.

 Since in system language there is plenty of ways to deliberately pass
 invalid data to the place where some validity assumptions were made,
 @disable is a broken feature.



Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 5:28 PM, deadalnix wrote:

The error lie in improper
initialization of p in the first place, which should never has been null. The
example looks dumb as this, you have to imagine the pattern hidden in thousands
of LOC.


I would find a design that declared a variable in one place, then initialized it 
in another, while releasing the lock in between as a bad design pattern to begin 
with. What other default initialized types could be there? What about an int 
default initialized to 0, yet code in another thread expects it to be some other 
value? I suspect there'd be a lot more bugs in it than just null pointer 
initializations.


It might be time to engineer a new pattern so you don't have to inspect 
thousands of LOC to manually verify correctness.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Walter Bright

On 5/19/2013 5:23 PM, John Colvin wrote:

On Sunday, 19 May 2013 at 20:45:39 UTC, Walter Bright wrote:

On 5/19/2013 1:03 PM, Maxim Fomin wrote:

I think there is difference between catching exception and saving
data which you have typed for some period and letting harware
check the exception for you meanwile loosing your work.


You can catch seg faults. It's easier on Windows, but it's doable on Linux.


What's the rational for not doing this by default in D? Wouldn't a
MemoryAccessError or similar be better than crashing out with SIGSEGV ?


Writing a seg fault handler under Linux has a large number of weird constraints.


I have
no idea about the consequences of this (other than tempting people to catch a
segfault when they shouldn't, which is pretty much always).


At some point, all the scaffolding and workarounds to try to prevent programmers 
from having to deal with the underlying reality of how the system works is not 
appropriate for a systems programming language.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread deadalnix

On Monday, 20 May 2013 at 01:08:16 UTC, Walter Bright wrote:

On 5/19/2013 5:28 PM, deadalnix wrote:

The error lie in improper
initialization of p in the first place, which should never has 
been null. The
example looks dumb as this, you have to imagine the pattern 
hidden in thousands

of LOC.


I would find a design that declared a variable in one place, 
then initialized it in another, while releasing the lock in 
between as a bad design pattern to begin with.


I cannot agree more. This is what made tracking the cause of the 
bug super hard.


What other default initialized types could be there? What about 
an int default initialized to 0, yet code in another thread 
expects it to be some other value? I suspect there'd be a lot 
more bugs in it than just null pointer initializations.


It might be time to engineer a new pattern so you don't have to 
inspect thousands of LOC to manually verify correctness.


I didn't programed Apache Cayenne, int he first place. But I had 
to patch it anyway.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-19 Thread Maxim Fomin

On Monday, 20 May 2013 at 00:55:14 UTC, Kenji Hara wrote:

Unfortunately this is currently not a bug.
T.init provides default initialized object image, and it 
*does not*
provide default constructed object. The difference is 
important.


That is already documented in lanugage reference.
http://dlang.org/property#init


Note: .init produces a default initialized object, not default

constructed. That means using .init is sometimes incorrect.
1. If T is a nested struct, the context pointer in T.init is 
null.
2. If T is a struct which has @disable this();, T.init might 
return a

logically incorrect object.

Kenji Hara



I think this should be fixed otherwise @disable this() is 
compromised. What is rationale behind allowing .init?




Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-18 Thread deadalnix

On Saturday, 18 May 2013 at 05:19:30 UTC, Maxim Fomin wrote:

On Saturday, 18 May 2013 at 02:34:46 UTC, Andrej Mitrovic wrote:

On 5/18/13, Timothee Cour thelastmamm...@gmail.com wrote:

S.init should be known at compile time by the spec.


But why is this needed?


It is needed in any place where such object is created due to 
default initialization. However if default ctor is CTFEable, 
dmd can support this feature.


Another solution is to issue an error when such object isn't 
initialized explicitely. This isn't very difficult to do.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-18 Thread deadalnix

On 5/17/13, Walter Bright wal...@digitalmars.com wrote:
I oppose this. D has a lot of nice features because of the 
.init property.

Default constructors wreck that.


So much great feature like :
 - null all over the place.
 - Having NUllable and NonNullable in phobos. BTW, NonNullable is 
unable to ensure that it if effectively non nullable.
 - Having to check for .init state all over the place (which have 
a runtime cost, in addition to be error prone). RefCounted 
implementation is emblematic of that.


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-18 Thread Walter Bright

On 5/18/2013 12:08 AM, deadalnix wrote:

On 5/17/13, Walter Bright wal...@digitalmars.com wrote:

I oppose this. D has a lot of nice features because of the .init property.
Default constructors wreck that.


So much great feature like :
  - null all over the place.
  - Having NUllable and NonNullable in phobos. BTW, NonNullable is unable to
ensure that it if effectively non nullable.
  - Having to check for .init state all over the place (which have a runtime
cost, in addition to be error prone). RefCounted implementation is emblematic of
that.


What default would you use for non-null pointers?


Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)

2013-05-18 Thread Jonathan M Davis
On Saturday, May 18, 2013 01:46:16 Igor Stepanov wrote:
 When programmer see constructor, he think that it will be
 evaluated each time when he create a new object.
 This code will seem obvious for any C++ coder.
 And this coder will be deceived.
 
 If we'll add default constructor to structs, we'll must safe of
 illusion, that constructor is called any time when new object
 have been created. And reject all cases when we can't provide
 this illusion.

Also, I really don't think that there's much point in having a default 
constructor if it's not executed at runtime. If it's going to be known at 
compile time, then just default initialize all of the members for the init 
value. What would a default constructor buy you?

It seems to me that a default constructor is useful in cases where you want to 
do stuff at runtime and the result can differ between executions of the program 
and possibly between instantions of that object - e.g. grabbing the computer's 
current IP or setting up the hourglass to display (which is how the hourglass 
is done in MFC).

And given the advantages of knowing a type's default value at compile time, I 
just don't see how we can have it be determined at runtime. So, while I think 
that there are cases where a default constructor could be quite useful, I 
don't see how we could usefully add it to D given how D deals with default 
initialization and everything that it does with that.

- Jonathan M Davis


  1   2   >