Proposal: Make [][x] and [][a..b] illegal (reserve for multidimensional arrays)

Bill Baxter dnewsgroup at billbaxter.com
Thu Nov 22 00:55:04 PST 2007


Don Clugston wrote:
> Bill Baxter wrote:
>> Don Clugston wrote:
>>>  > Bill Baxter wrote:
>>>  >>> 2) D lacks a clean syntax for slices of multiple dimensions.  
>>> opSlice
>>>  >>> calls must have one and only one ".."
>>>  >>
>>>  >> Can you propose a syntax for that?
>>>
>>> How about making [] more than just a shorthand for [0..$], but rather 
>>> mean "take everything from this dimension and move on".
>>> This would, I think, make it more consistent with its usage in 
>>> declarations, where it is a dimension marker, not a slice.
>>>
>>> This would leave the way open for multidimensional array slicing.
>>> For example, access of 5 dimensions would be of the form
>>> auto c = m[][4][][][7];
>>>
>>> where [] = take the whole contents of that dimension, or [x] takes 
>>> only element x of it. Just as now, there is an implicit [][][] at the 
>>> end for any unspecified dimensions.
>>>
>>> A slice can be inserted in the expression before any dimension is 
>>> completed; it takes a slice of that dimension.
>>> So, for example, with a 2-D matrix m,
>>> auto c = m[4..5][][1];
>>>
>>> would mean [ m[4][1], m[5][1] ].
>>> and m[1][4..5] == m[1][4..5][];
>>>
>>> would continue to mean [ m[1][4], m[1][5] ].
>>>
>>> You can do this right now for user-defined types, but built-in types 
>>> work differently because of a (IMHO) useless redundancy.
>>>
>>>     int f[][2] = [[1,2], [3,4], [5,6], [7,8]];
>>>     int [] e = f[][1];
>>>     int [] g = f[1][];
>>>     int [] h = f[1];
>>>     int [] p = f[][][][][][][1][][][][][][][][][][][][]; // isn't 
>>> this silly???
>>>
>>> Currently this is legal. All those expressions are synonyms.
>>> e[0] == g[0] == h[0] == p[0] == f[1][0] == 3.
>>> In my proposal e would mean:
>>> f[0][1], f[1][1], f[2][1], f[3][1]
>>> which would become illegal since it is a strided slice (currently 
>>> unsupported in the language)
>>> and g would be:
>>> f[1][0], f[1][1]
>>> which is the same as h.
>>> In fact, right now, in an expression, any slicing or indexing 
>>> operation on a built-in array after a [] would become illegal.
>>>
>>> This would only break existing code which contained (IMHO) bad style 
>>> and confusing redundancy.
>>> If for some reason the existing behaviour was desired (such as in 
>>> metaprogramming or code generation ?), simply change [] to [0..$].
>>> But [] would continue to provide syntactic sugar in the places it was 
>>> originally intended.
>>
>> What would this give you?
>>   float[] x;
>>   auto y = x[]; // what's y's type?
>>
>> Or would that be just like it is now, a float[]?  If so then it seems 
>> like you lose some syntactical associativity.  That is, (x[])[] would 
>> no longer be the same as x[][].
> 
> Yes, that's a problem. My original idea was that it would be remembered 
> throughout the expression -- but I think that would mean it ends up 
> being context-sensitive. I think that the only way it could work is to 
> disallow [] in any situation where it is redundant; which would end up 
> breaking almost all existing code that uses it.
> 
>>
>> Another proposal would be to allow [..] as your slice an move on 
>> syntax, and keep the current meaning of [].
> 
> That would be preferable, and more intuitive, but would break existing 
> code.
> 
> 
>> Anyway, f[i][j][k] syntax is much more difficult to read than 
>> f[i,j,k].  So I think the latter is what we should be shooting for.
> 
> That's a reasonable argument. In which case it should be a high priority 
> to make the comma operator illegal inside array declarations. It seems 
> to me that so much nonsensical syntax is legal at present, that there's 
> hardly any room to maneuver.
> 
> Curiously,  float[3,4] a; is legal, (and is equivalent to float [4] a;)
> but a[2,3]
> generates:
>  Error: only one index allowed to index float[4u]
> 
> which is a pretty strong indicator that Walter intends to support 
> [i,j,k] syntax at some point.

There's more than just intent.  It works fine.  Write yourself an 
opIndex(int,int,int) and try it out.  opIndexAssign(Value v, 
int,int,int) type things work too.  opIndex(MyStruct,Object,Object) even 
works.   The hole in functionality right now is just in the intersection 
of multiple indices and slices.  But since you can have Object/struct 
indices you can create your slicing scheme using a custom Slice type for 
indices.  You just can't have $ or .. syntax (at least .. in any other 
form than foo[A..B].

> I therefore retract this proposal.
> 
> Basically I just want _some_ syntax which to support in BLADE (doesn't 
> matter what, I can pretty much do anything) and so I want to match what 
> D will eventually allow in normal code.
> (For example, I can check for the existence of
>   opBladeDollar(int dimension)  and
>   opBladeSlice(uint DimensionReduction)(uint slices[2])
> where slice[x][0]=start of slice, [x][1] = end of slice, and start==end 
> if it's an index rather than a slice, and DimensionReduction is number 
> of indexing operations so that you can determine the return type).

--bb



More information about the Digitalmars-d mailing list