www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Pull 375 and related enhancements

reply bearophile <bearophileHUGS lycos.com> writes:
I discuss this here because I think this deserves a wider and more visible
discussion.

This is pull request 375 by the _very_ good Kenji Hara:
https://github.com/D-Programming-Language/dmd/pull/375

It fixes (or tries to fix) several old and new issues with arrays and array
literals, including one that has caused me several troubles in real code:
http://d.puremagic.com/issues/show_bug.cgi?id=2356

This one related discussion thread:
http://d.puremagic.com/issues/show_bug.cgi?id=5290

It seems Pull 375 also turns this program in a compile-time error:

int[3] arr = [1, 2];
void main() {}

Walter told me that this code used to work as designed, this means it's not a
bug.
Despite not being a bug, I think accepting that kind of code is a bug-prone
anti-feature.

There are two little enhancement requests related to this (not currently
implemented in Pull 375): Walter wants this code to work because in some
uncommon situations he wants to be free to specify less items than the whole
array:

int[3] arr = [1, 2];
void main() {}


The Python Zen says "Explicit is better than implicit.". Being explicit allows
Walter to do what he wants, and allows me to avoid the bugs too.

So I (and other people) have suggested this syntax for the uncommon situations
where you want to specify less items:

int[3] arr = [1, 2, ...];

A related enhancement request solves a little problem I have with D array
literals:

int[$] arr = [10,2,15,15,14,12,3,7,13,5,9,9,7,9,9,9,11,15,1,1,12,5,14];

This avoids me to manually count how many items there are on the right.

Keep in mind that if I write this it currently compiles, despite being a BUG:

int[24] arr = [10,2,15,15,14,12,3,7,13,5,9,9,7,9,9,9,11,15,1,1,12,5,14];
void main() {}

In my opinion a good compiler has to prevent this bug.

Bye,
bearophile
Sep 09 2011
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/9/2011 11:48 AM, bearophile wrote:
 It seems Pull 375 also turns this program in a compile-time error:

 int[3] arr = [1, 2];
 void main() {}

 Walter told me that this code used to work as designed, this means it's not a
bug.
 Despite not being a bug, I think accepting that kind of code is a bug-prone
anti-feature.
The point of that working is that it isn't unusual to have a large array with only the front of it initialized.
Sep 09 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/9/11, Walter Bright <newshound2 digitalmars.com> wrote:
 On 9/9/2011 11:48 AM, bearophile wrote:
 It seems Pull 375 also turns this program in a compile-time error:

 int[3] arr = [1, 2];
 void main() {}

 Walter told me that this code used to work as designed, this means it's
 not a bug.
 Despite not being a bug, I think accepting that kind of code is a
 bug-prone anti-feature.
The point of that working is that it isn't unusual to have a large array with only the front of it initialized.
Some consistency would be good then: int[3] arr = [1, 2]; // ok void main() { int[3] arr2 = [1, 2]; // fails at runtime }
Sep 09 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Walter:

 The point of that working is that it isn't unusual to have a large array with
 only the front of it initialized.
I have not proposed to forbid that (despite I think Pull 375 forbids it) (despite I think I have never had this need), but just to make this explicit syntax-wise, instead of implicit, not much visible, and bug-prone. Explicit is often better than implicit. ------------------------ Andrej Mitrovic:
     int[3] arr2 = [1, 2];  // fails at runtime
With the latest Pull this will fail at compile-time (well, both of them). Bye, bearophile
Sep 09 2011
prev sibling next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2011/9/10 Andrej Mitrovic <andrej.mitrovich gmail.com>:
 Some consistency would be good then:

 int[3] arr =3D [1, 2]; =A0// ok
 void main()
 {
 =A0 =A0int[3] arr2 =3D [1, 2]; =A0// fails at runtime
 }
Wow, I didn't know that global level initializing and local variable initializing are different. Sorry, my patch rejects arr2, but don't reject arr3. Kenji Hara
Sep 09 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/9/2011 8:01 PM, kenji hara wrote:
 Wow, I didn't know that global level initializing and local variable
 initializing are different.
One is compile time, the other runtime, and they are used for very different purposes.
Sep 09 2011
parent Jeff Nowakowski <jeff dilacero.org> writes:
On 09/09/2011 11:48 PM, Walter Bright wrote:
 One is compile time, the other runtime, and they are used for very
 different purposes.
Too bad you aren't responding to the bug-prone functionality for a minor feature and a proposed syntax fix for it. This is like switch fallthrough all over again.
Sep 10 2011
prev sibling parent reply Don <nospam nospam.com> writes:
On 09.09.2011 21:53, Walter Bright wrote:
 On 9/9/2011 11:48 AM, bearophile wrote:
 It seems Pull 375 also turns this program in a compile-time error:

 int[3] arr = [1, 2];
 void main() {}

 Walter told me that this code used to work as designed, this means
 it's not a bug.
 Despite not being a bug, I think accepting that kind of code is a
 bug-prone anti-feature.
The point of that working is that it isn't unusual to have a large array with only the front of it initialized.
Do you have an example? The best I could come up with with was: char [80] buff = "Hello, world!\n"; but that generates a "lengths don't match for array copy" error at runtime. So I find it hard to invent a use case. But I have been bitten by getting the lengths wrong on numerous occasions, eg it happened several times in std.mathspecial.
Sep 11 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

 Do you have an example?
In bug 3849 there the only example I've found (it's not my code): immutable ubyte _ctype[256] = [ _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL, ... ]; (ellipses added by me). But I have never had to do something like that in my code, so far. Stewart Gordon has recently written more comments about this topic (is Bugzilla down?): http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=32924 Bye, bearophile
Sep 11 2011
parent reply Don <nospam nospam.com> writes:
On 11.09.2011 11:43, bearophile wrote:
 Don:

 Do you have an example?
In bug 3849 there the only example I've found (it's not my code): immutable ubyte _ctype[256] = [ _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL, ... ]; (ellipses added by me). But I have never had to do something like that in my code, so far.
Thanks! We could do this with CTFE, for example: immutable ubyte _ctype[256] = padArrayLiteral(256, [ _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, ... _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL ], 0); and this would also work with Stewart's example. I don't think we really need language support, the language already has enough power to do this kind of thing in a library.
 Stewart Gordon has recently written more comments about this topic (is
Bugzilla down?):
 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=32924

 Bye,
 bearophile
Sep 12 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Don:

 Thanks! We could do this with CTFE, for example:
 
 immutable ubyte _ctype[256] = padArrayLiteral(256,
 	[
            _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,
 ...
            _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL
 	], 0);
 
 and this would also work with Stewart's example.
 I don't think we really need language support, the language already has 
 enough power to do this kind of thing in a library.
The ... syntax seems even less needed, if you add that to Phobos. But the $ syntax is useful still. Bye, bearophile
Sep 12 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/11/2011 2:31 AM, Don wrote:
 Do you have an example?
One is initializing the ctype array - the first 128 are initialized, followed by 128 zeros.
Sep 12 2011
parent reply Don <nospam nospam.com> writes:
On 12.09.2011 12:47, Walter Bright wrote:
 On 9/11/2011 2:31 AM, Don wrote:
 Do you have an example?
One is initializing the ctype array - the first 128 are initialized, followed by 128 zeros.
As I said in my other post, we could deal with this using a CTFE library solution. It hardly seems common enough to justify the special-case syntax sugar in the language, especially when it masks a common bug.
Sep 12 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

 As I said in my other post, we could deal with this using a CTFE library 
 solution.
Currently this works: ubyte[10] a = [1, 2]; void main() {} But if you write this, I think padArrayLiteral returns an int[], so D refuses the implicit cast: ubyte[10] a = padArrayLiteral(256, [1, 2]); void main() {} So I think you have to write something like: ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]); void main() {} Bye, bearophile
Sep 12 2011
next sibling parent kennytm <kennytm gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:
 Don:
 
 As I said in my other post, we could deal with this using a CTFE library 
 solution.
Currently this works: ubyte[10] a = [1, 2]; void main() {} But if you write this, I think padArrayLiteral returns an int[], so D refuses the implicit cast: ubyte[10] a = padArrayLiteral(256, [1, 2]); void main() {}
Why you're padding to 256 entries when a ubyte[10] is needed? ;)
 So I think you have to write something like:
 
 ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]);
 void main() {}
 
 Bye,
 bearophile
Or: auto a = staticArray!(ubyte[10])([1, 2]); (staticArray() is like array() which can take arbitrary ranges, but it returns a static array formed by take-ing the range and padding with ElementType.init.)
Sep 12 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:j4krf0$2070$1 digitalmars.com...
 Don:

 As I said in my other post, we could deal with this using a CTFE library
 solution.
Currently this works: ubyte[10] a = [1, 2]; void main() {} But if you write this, I think padArrayLiteral returns an int[], so D refuses the implicit cast: ubyte[10] a = padArrayLiteral(256, [1, 2]); void main() {} So I think you have to write something like: ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]); void main() {}
I think you mean: auto a = padArrayLiteral!ubyte(10, [1, 2]); void main() {} ? ------------------------------- Not sent from an iPhone.
Sep 12 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 I think you mean:
 
 auto a = padArrayLiteral!ubyte(10, [1, 2]);
 void main() {}
I think Don knows what I meant :-) I meant something like: ubyte[256] a = padArrayLiteral!ubyte(256, [1, 2]); Bye and sorry, bearophile
Sep 12 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:j4dn1c$244l$1 digitalmars.com...
 It seems Pull 375 also turns this program in a compile-time error:

 int[3] arr = [1, 2];
 void main() {}

 Walter told me that this code used to work as designed, this means it's 
 not a bug.
 Despite not being a bug, I think accepting that kind of code is a 
 bug-prone anti-feature.

 There are two little enhancement requests related to this (not currently 
 implemented in Pull 375): Walter wants this code to work because in some 
 uncommon situations he wants to be free to specify less items than the 
 whole array:

 int[3] arr = [1, 2];
 void main() {}


 The Python Zen says "Explicit is better than implicit.". Being explicit 
 allows Walter to do what he wants, and allows me to avoid the bugs too.
In general, I consider Python Zen to be a load of puritanical BS (no offence ;)). But I definitely agree that the ability to do "T[n] x = [ {<n} ];" is a terrible hidden landmine.
 So I (and other people) have suggested this syntax for the uncommon 
 situations where you want to specify less items:

 int[3] arr = [1, 2, ...];
+1...on the condition that such an ability really is all that useful anyway. (I can't think of a single time I've ever wanted to do that.)
Sep 09 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 int[3] arr = [1, 2, ...];
+1...on the condition that such an ability really is all that useful anyway. (I can't think of a single time I've ever wanted to do that.)
So far I have never had to do it, despite I have written a good amount of Ada-style code in D. I (and others) have suggested that syntax because Walter wants to do that. The solution is to add some symbol that explicitly marks the array as not complete, so both the compiler and the person that later reads the code knows some items are missing. If no item is missing the compiler probably has to generate an error again: int[2] arr = [1, 2, ...]; // compile-time error I think that syntax is explicit and readable enough. A problem with this idea is this syntax is probably not used often. On the other hand leaving that trap in the D language is not good at all. The idea of the dollar symbol can't be used with the ellipsis symbol: int[$] arr = [1, 2, ...]; // compile-time error again Note: for me this syntax with $ is more commonly useful compared to the "..." syntax. Bye, bearophile
Sep 10 2011
parent reply zeljkog <zeljkog private.com> writes:
On 10.09.2011 11:30, bearophile wrote:
 Note: for me this syntax with $ is more commonly useful compared to the "..."
syntax.
I think that the proposed use of the operator $ a consistent and intuitive in the context. In this case ellipsis is unnecessary, "int [N] = [1];" automatically gets a second intuitive meaning, consistent with the struct literal. Question remains is it worth?
Sep 11 2011
parent bearophile <bearophileHUGS lycos.com> writes:
zeljkog:

 I think that the proposed use of the operator $ a consistent and intuitive in
the context.
 In this case ellipsis is unnecessary, "int [N] = [1];" automatically gets a
second intuitive meaning, consistent with the struct literal.
I don't understand what's the second intuitive meaning, so maybe it's not intuitive for me :-(
 Question remains is it worth?
In my opinion the $ syntax is worth regardless, because it saves me some time and some mistakes, it's short, I think it doesn't clash with other already present syntaxes, it's an additive change to D so it's backwards compatible and doesn't require deprecations, and probably a D programmer is able to understand/remember its meaning the second time he/she sees it, with no need to look in the D docs again (there are other D syntaxes that require me still to look in the D docs despite I have used them several times). I don't know if the ellipsis syntax is worth it, it is meant to allow an uncommon case. Bye, bearophile
Sep 11 2011