March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer:
> I would favor just changing the behavior.
If you just change the behavior, then I suggest to take in account associative arrays too:
void main() {
bool[int] aa;
assert(!aa);
aa = [1: true];
assert(aa);
aa.remove(1);
assert(aa);
assert(!aa.length);
}
Bye,
bearophile
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Mon, 25 Mar 2013 11:04:58 -0400, bearophile <bearophileHUGS@lycos.com> wrote:
> Steven Schveighoffer:
>
>> I would favor just changing the behavior.
>
> If you just change the behavior, then I suggest to take in account associative arrays too:
>
>
> void main() {
> bool[int] aa;
> assert(!aa);
> aa = [1: true];
> assert(aa);
> aa.remove(1);
> assert(aa);
> assert(!aa.length);
> }
This can be done without compiler changes. Just define opCast!bool for AssocArray (or whatever the template is, I can't remember).
I do agree this should be done too.
-Steve
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer: > Just define opCast!bool for AssocArray (or whatever the template is, I can't remember). I opened an ER about this topic too :-) http://d.puremagic.com/issues/show_bug.cgi?id=3926 Bye, bearophile |
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2013-03-24 23:10, bearophile wrote: > A recent discussion in D.learn reminds me of an enhancement request of > mine that is sleeping in Bugzilla since years: > > http://d.puremagic.com/issues/show_bug.cgi?id=4733 > > > The probles is that in D dynamic arrays can be non-null even when they > are empty: > > > import std.stdio; > int[] foo() { > auto a = [1]; > return a[0..0]; > } > void main() { > auto data = foo(); > if (data) > writeln("here"); > } > > > This is dangerous, so in D the safe and idiomatic way to test for empty > arrays is to use std.array.empty(). > > So my proposal of Issue 4733 is to forbid (with the usual > warning/deprecation intermediate steps) the use of dynamic arrays in a > boolean context: > > > void main() { > auto a = [1]; > if (a) {} // error, forbidden. > } > > > So to test empty/null you have to use empty() or "is null": > > import std.array: empty; > void main() { > auto a = [1]; > if (a.empty) {} // OK > if (a is null) {} // OK > } I just started to use this in one place :( if (auto a = getArray()) { } getArray returns null if now array exists. -- /Jacob Carlborg |
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, 24 March 2013 at 22:10:06 UTC, bearophile wrote:
> A recent discussion in D.learn reminds me of an enhancement request of mine that is sleeping in Bugzilla since years:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=4733
>
>
> The probles is that in D dynamic arrays can be non-null even when they are empty:
>
>
> import std.stdio;
> int[] foo() {
> auto a = [1];
> return a[0..0];
> }
> void main() {
> auto data = foo();
> if (data)
> writeln("here");
> }
>
>
> This is dangerous, so in D the safe and idiomatic way to test for empty arrays is to use std.array.empty().
>
> So my proposal of Issue 4733 is to forbid (with the usual warning/deprecation intermediate steps) the use of dynamic arrays in a boolean context:
>
>
> void main() {
> auto a = [1];
> if (a) {} // error, forbidden.
> }
>
>
> So to test empty/null you have to use empty() or "is null":
>
> import std.array: empty;
> void main() {
> auto a = [1];
> if (a.empty) {} // OK
> if (a is null) {} // OK
> }
>
>
> Bye,
> bearophile
Hi,
IMHO, somebody coming from a C/C++ background (like me) has no problem realizing that if( var ) means either if not null or if not 0. There was talk about changing the behavior of if( arr ) to mean if( !arr.empty ) but I believe this is the worst thing to do, since it would incorporate some inconsistencies with usual pointers.
int[] foo() { auto var = new int[ 0 ]; return var; }
int * bar() { auto var = cast( int * )malloc( 0 ); return var; }
void main() {
if( foo() ) {
//Would not pass, since foo is empty.
}
if( bar() ) {
//Would pass, since bar is not null.
}
}
I prefer to have code that explicitly states what is going on anyways:
if( arr !is null && !arr.empty ) { blablabla; }
Whenever somebody decides to used the abbreviated expression if(arr), I think that the behavior should be the one of the C language. I'm not sure it is wise just yet to establish that whenever somebody test a slice to see if it's null that somebody also means to test if it is empty.
Interesting idea though.
Cheers!
Phil
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Monday, 25 March 2013 at 14:09:33 UTC, bearophile wrote:
>> Seems like a sensible idea. I've never really understood why null is acceptable as a slice anyway. It's not a class, so it shouldn't be allowed.
>
> Maybe you are confusing issue 4733 with this other one:
> http://d.puremagic.com/issues/show_bug.cgi?id=3889
Not confusing, just making a tangential remark. I understand your proposal :-)
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Phil Lavoie | Phil Lavoie: > IMHO, somebody coming from a C/C++ background (like me) has no problem realizing that if( var ) means either if not null or if not 0. Some D programmers come from other languages, where if(arr) means if its len is different from zero. D dynamic arrays are 2 words, so you can have a length zero with a not-null pointer. So there is space for some semantic confusion. > There was talk about changing the behavior of if( arr ) to mean if( !arr.empty ) but I believe this is the worst thing to do, since it would incorporate some inconsistencies with usual pointers. D dynamic arrays aren't pointers, they are composed of two words, so you can't assume the semantics is exactly the same. I think assuming if(arr) means if(!arr.empty) is still better than the current situation :-) Bye, bearophile |
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Monday, 25 March 2013 at 16:14:18 UTC, bearophile wrote:
> Phil Lavoie:
>
>> IMHO, somebody coming from a C/C++ background (like me) has no problem realizing that if( var ) means either if not null or if not 0.
>
> Some D programmers come from other languages, where if(arr) means if its len is different from zero.
>
> D dynamic arrays are 2 words, so you can have a length zero with a not-null pointer. So there is space for some semantic confusion.
>
>
>> There was talk about changing the behavior of if( arr ) to mean if( !arr.empty ) but I believe this is the worst thing to do, since it would incorporate some inconsistencies with usual pointers.
>
> D dynamic arrays aren't pointers, they are composed of two words, so you can't assume the semantics is exactly the same.
>
> I think assuming if(arr) means if(!arr.empty) is still better than the current situation :-)
>
> Bye,
> bearophile
Herro,
Of course you can argue that not every programmers come from C/C++ background, but, if I'm correct, D is aimed to be a C++ replacement, right? On the other hand, C is like the most used language on the universe (aliens included), so it makes sense to consider its expression semantics first. I am aware that those aren't the strongest arguments, but if we'd have to compare programmer backgrounds to make a decision regarding expression behaviors, I think C should win.
Obviously, slices are not single word pointers, but they are pointers after all (or at the very least own one). Just saying that comparing a slice for its initial state or an invalid state is not the same as checking length, but I think we agree on that.
Where we disagree is on default behavior of if(arr). You think it should check for length to be more programmer friendly, or rather, avoid unwanted errors (though if I was that programmer, I would not think it's friendly at all :( ) whereas I think it should act as if it was a pointer in C.
Since it is already the behavior of the language, on a scale of 10, how would you prioritize your suggestion :D? How much of a change do you think it would make? I respect your opinions and suggestions, though I have never fell in the trap you presented in your opening statement :), nor did I even think someone would.
I do believe that, in any case, this form is best:
if( arr !is null && !arr.empty )
Peace,
Phil
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Phil Lavoie | 25-Mar-2013 20:43, Phil Lavoie пишет: > I do believe that, in any case, this form is best: > if( arr !is null && !arr.empty ) > Now write that one thousand times and count the typos. > Peace, > Phil -- Dmitry Olshansky |
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 03/24/2013 11:10 PM, bearophile wrote:
> A recent discussion in D.learn reminds me of an enhancement request of
> mine that is sleeping in Bugzilla since years:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=4733
>
>
> The probles is that in D dynamic arrays can be non-null even when they
> are empty:
>
>
> import std.stdio;
> int[] foo() {
> auto a = [1];
> return a[0..0];
> }
> void main() {
> auto data = foo();
> if (data)
> writeln("here");
> }
>
>
> This is dangerous, so in D the safe and idiomatic way to test for empty
> arrays is to use std.array.empty().
>
> So my proposal of Issue 4733 is to forbid (with the usual
> warning/deprecation intermediate steps) the use of dynamic arrays in a
> boolean context:
>
>
> void main() {
> auto a = [1];
> if (a) {} // error, forbidden.
> }
>
>
> So to test empty/null you have to use empty() or "is null":
>
> import std.array: empty;
> void main() {
> auto a = [1];
> if (a.empty) {} // OK
> if (a is null) {} // OK
> }
> ...
Well, cast(bool)a currently checks a.ptr:
void main(){
auto x = (cast(void*)null)[0..1];
assert(x !is null);
assert(x);
}
Also, IMO null arrays should either be removed or [] should be guaranteed to be non-null.
Maybe cast(bool)a simply shouldn't work. (though, personally, I'd lean towards checking length.)
|
Copyright © 1999-2021 by the D Language Foundation