RFC on range design for D2

Oskar Linde oskar.lindeREM at OVEgmail.com
Thu Sep 11 09:08:40 PDT 2008


First, let me add my support for the range proposal. It is in line with 
earlier suggestions but makes some crucial additions. I'm also very glad 
that one of the most influencing forces behind D has returned to those 
newsgroups.

Andrei Alexandrescu wrote:
> Robert Jacques wrote:
>> On Mon, 08 Sep 2008 20:37:41 -0400, Andrei Alexandrescu 
>> <SeeWebsiteForEmail at erdani.org> wrote:
>>> Denis Koroskin wrote:
>>>> 4) We need some way of supporting dollar notation in user 
>>>> containers. The hack of using __dollar is bad (although it works).
>>>
>>> It doesn't work for multiple dimensions. There should be an 
>>> opDollar(uint dim) that gives the library information on which 
>>> argument count it occured in. Consider:
>>>
>>> auto x = matrix[$-1, $-1];
>>>
>>> Here the dollar's occurrences have different meanings. A good start 
>>> would be to expand the above into:
>>>
>>> auto x = matrix[matrix.opDollar(0)-1, matrix.opDollar(1)-1];
>>
>> I'd also add that multiple dimension slicing should be supported. i.e.
>> auto x = matrix[2..5,0..$,3]
>> would become
>> auto x = 
>> matrix.opSlice(Slice!(size_t)(2,5),Slice!(size_t)(0,matrix.opDollar(0)),3) 
>>
>> with
>> struct Slice (T) { T start; T end; }
>> Strided slices would also be nice. i.e. matrix[0..$:10] // decimate 
>> the array
> 
> Multidimensional slicing can be implemented with staggered indexing:
> 
> matrix[2..5][0..$][3]
> 
> means: first, take a slice 2..5 that returns a matrix range one 
> dimension smaller. Then, for that type take a slice from 0 to $. And so on.

Implementing multidimensional slicing in this way is quite irregular. 
One would expect m[2..5][1..2] to behave just like s[2..5][1..2] would 
for a regular array. (e.g. consider s being of the type char[]).

I implemented most of all of this (multidimensional arrays) a little 
more than two years ago. (Being able to implement it required me to 
write the patch that made it into DMD 0.166 that made it possible for 
structs and classes to have template member functions/operators.)

There was basically one Matrix type with rectangular, dense storage and 
a strided Slice type. I believe the only thing that makes sense when it 
comes to multidimensional slicing is how I implemented it:

m[i_1, i_2, i_3, ...],

where i_x is either a range or a singular index, and x corresponds to 
the dimension (1,2,3,...) results in a slice where each dimension 
indexed by a singular index is collapsed and dimensions indexed by a 
range is kept.

The resulting syntax is:

m[range(2,5), all, 3, range($-1,$)]

even though the possibility to use $ like this wasn't discovered until 
much later.

Of course, the optimal syntax would be something like:

m[2..5, 0..$, 3, $-1..$],

which would be easiest to implement by making a..b a value in it self of 
an integral range type. Intriguingly, integral ranges would just be an 
implementation of the same range concept you have already presented.

-- 
Oskar


More information about the Digitalmars-d-announce mailing list