March 24, 2013 Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
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 |
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:
> 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:
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.
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | Peter Alexander: > On Sunday, 24 March 2013 at 22:10:06 UTC, bearophile wrote: >> 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: > > 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 Unlike Issue 4733, issue 3889 doesn't cause bugs, so it's less important. Here I am not asking to disallow null as a slice. I am asking to disallow the implicit cast "dynamic array => bool". Because it's a source of bugs and there are simple & more explicit ways to do the same thing if you want to. Bye, bearophile |
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:
> import std.array: empty;
> void main() {
> auto a = [1];
> if (a.empty) {} // OK
> if (a is null) {} // OK
> }
>
>
> Bye,
> bearophile
why not a.length == 0 ?
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | "bearophile" <bearophileHUGS@lycos.com> wrote in message news:bwgnbflygowctlisistg@forum.dlang.org... > 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: I am in favour of deprecating/removing this, then bringing it back so that if (arr) is the same as if (arr.length) |
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana:
> why not a.length == 0 ?
a.length == 0 is OK of course, it's the same thing as writing a.empty.
Bye,
bearophile
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | Daniel Murphy:
> I am in favour of deprecating/removing this, then bringing it back so that
> if (arr)
> is the same as
> if (arr.length)
That was my original idea :-) And it seems a nice idea.
But turning something into a deprecation and later error is useful because it doesn't introduce bugs. While if you later assign it some other semantics, old D code will behave differently (despite it's probably potentially buggy code in the first place).
So it's a matter of how much you want to break old D code.
Bye,
bearophile
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Monday, 25 March 2013 at 14:20:27 UTC, bearophile wrote:
> Andrea Fontana:
>
>> why not a.length == 0 ?
>
> a.length == 0 is OK of course, it's the same thing as writing a.empty.
>
> Bye,
> bearophile
Is empty() there just to match range "interface"?
length needs no import :)
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy | On Mon, 25 Mar 2013 10:18:11 -0400, Daniel Murphy <yebblies@nospamgmail.com> wrote:
> "bearophile" <bearophileHUGS@lycos.com> wrote in message
> news:bwgnbflygowctlisistg@forum.dlang.org...
>> 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:
>
> I am in favour of deprecating/removing this, then bringing it back so that
> if (arr)
> is the same as
> if (arr.length)
I would favor just changing the behavior. The existing behavior is most often a bug when it is used, because quite often arrays are null (that is the default value), and quite often, people THINK they are checking if the array is empty instead of if the pointer is null. Because most empty arrays are null, and null arrays have zero length, their tests do not expose this bug. It's actually very difficult to generate a non-null empty array for testing. [] does not work, it returns a null array!
Only in rare cases do people actually want to check for null, and in most people's code it is an error when a non-null but empty array is checked with if(arr). If people are interested in the pointer, they usually check if(arr.ptr) or if(arr !is null).
I would posit that for every knowledgeable person who uses this "shortcut" to check for null, 100 people use it expecting it to be measuring the array length.
If we go through a deprecation cycle, it makes people who do if(arr) for length have to change there code to if(arr.length) then back to if(arr) once the deprecation is over. The switch to if(arr.length) will be simple, the compiler will show all the places if(arr) is used, but the switch back will be more difficult since if(arr.length) will not be deprecated.
What about a switch that identifies all places where if(arr) is done? Then people who use if(arr) for testing if(arr.ptr) can find and fix their cases. Or even a separate tool to do that.
-Steve
|
March 25, 2013 Re: Forbid dynamic arrays in boolean evaluation contexts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | Andrea Fontana: > Is empty() there just to match range "interface"? Right, it's useful for arrays to fulfill the range protocol. > length needs no import :) On the other hand in a longhish module you sometimes need std.array for other purposes, so you have imported it already. "data.empty" is shorter, and it contains only two (psychological) chunks, while "data.length == 0" contains four. So empty makes the code simpler. And empty doesn't break the syntax uniformity of UFCS chains :-) Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation