This makes perfect sense to me as a new-comer, and having not had much experience writing this sort of code, this is exactly how I would have assumed it is now. I would have been in for a confusing surprise had I tried to do any of this stuff.
On 16 November 2011 05:24, bearophile <bearophileh...@lycos.com> wrote: > The Bugzilla issues that I really care about is a not an useless long > list, it's about fifteen items long, and this post is about one of them. > > I think current array slice assign syntax is a bit messy, and I think this > should be addressed. > > Kenji Hara has recently written a very nice program (that here I have > modified a bit for clarity) that shows the current array assign situation: > > > import std.stdio, std.typetuple; > > void main() { > writeln("Rhs is an array, is it compilable?"); > writeln("a\t/ b\t\ta=b\ta[]=b\ta=b[]\ta[]=b[]"); > > foreach (i, Lhs; TypeTuple!(int[3], int[])) > foreach (j, Rhs; TypeTuple!(int[3], int[])) { > writef("%s\t/ %s ", Lhs.stringof, Rhs.stringof); > Lhs a = [0,0,0]; > Rhs b = [1,2,3]; > writef("\t%s", __traits(compiles, { a = b; })); > writef("\t%s", __traits(compiles, { a[] = b; })); > writef("\t%s", __traits(compiles, { a = b[]; })); > writef("\t%s", __traits(compiles, { a[] = b[]; })); > writeln(); > } > > > writeln("\nRhs is a element, is it compilable?"); > writeln("a\t\t\ta=N\ta[]=N\ta[0..2]=N"); > > foreach (Lhs; TypeTuple!(int[3], int[])) { > writef("%s\t\t", Lhs.stringof); > Lhs a = [0,0,0]; > writef("\t%s", __traits(compiles, { a = 9; })); > writef("\t%s", __traits(compiles, { a[] = 9; })); > writef("\t%s", __traits(compiles, { a[0..2] = 9; })); > writeln(); > } > } > > > > Currently (DMD 2.057head, despite I think Walter has not updated DMD > version number yet) it prints: > > > Rhs is an array, is it compilable? > a / b a=b a[]=b a=b[] a[]=b[] > int[3u] / int[3u] true true true true > int[3u] / int[] true true true true > int[] / int[3u] true true true true > int[] / int[] true true true true > > Rhs is a element, is it compilable? > a a=N a[]=N a[0..2]=N > int[3u] true true true > int[] false true true > > > > This also means this is currently accepted: > > void main() { > int[3] a; > a = 1; > assert(a == [1, 1, 1]); > } > > > While this is not accepted: > > void main() { > int[] b = new int[3]; > b = 1; > assert(b == [1, 1, 1]); //Error: cannot implicitly convert expression > (1) of type int to int[] > } > > > > I'd like D to require a[]=1 in that first case too. > > I'd like the [] to be required every time an O(n) vector operation is > done, for: > - constancy with all other vector operations among two arrays, that > require []; > - and to avoid unwanted (and not easy to spot in the code) O(n) operations; > - bugs and confusion in D newbies that don't have memorized all current > special cases. > > On the other hand Don says that [] is only required for lvalues. > > I think this boils to a new table like this: > > > Rhs is an array, is it compilable? > a / b a=b a[]=b a=b[] a[]=b[] > int[3u] / int[3u] FALSE true FALSE true > int[3u] / int[] FALSE true FALSE true > int[] / int[3u] FALSE true FALSE true > int[] / int[] true true true true > > Rhs is a element, is it compilable? > a a=N a[]=N a[0..2]=N > int[3u] FALSE true true > int[] false true true > > > Now if there's a [] on the left, then it's an O(n) vector operation (like > a copy), otherwise it's O(1). > > That also means: > > void main() { > int[] a = new int[3]; > int[] b = new int[3]; > a = b; // OK, copies just array fat reference > } > > void main() { > int[3] a, b; > a = b; // Not OK, hidden vector op > } > > > I am not sure this new table is fully correct, but it's a start. Fixes of > mistakes are welcomes. > > ----------------------- > > This is an alternative proposal. > > On the other hand this vector op syntax doesn't currently compile: > > void main() { > int[3] a, b; > a[] += b; > } > > > So if array assign is seen as a normal vector op, then the [] is needed on > the right too: > > > Rhs is an array, is it compilable? > a / b a=b a[]=b a=b[] a[]=b[] > int[3u] / int[3u] FALSE FALSE FALSE true > int[3u] / int[] FALSE FALSE FALSE true > int[] / int[3u] FALSE FALSE FALSE true > int[] / int[] true FALSE FALSE true > > Rhs is a element, is it compilable? > a a=N a[]=N a[0..2]=N > int[3u] FALSE true true > int[] false true true > > > Where the two cases with dynamic arrays are syntax errors to keep more > symmetry: > > void main() { > int[] a = new int[3]; > int[] b = new int[3]; > a[] = b; // error > a = b[]; // error > } > > ----------------------- > > Lot of time ago I have opened bug issue 3971 on this topic, but that > Bugzilla thread contains various mistakes and some parts of it are obsolete. > > Bye, > bearophile >