opSlice and $

Bill Baxter dnewsgroup at billbaxter.com
Tue Sep 11 15:15:31 PDT 2007


Oskar Linde wrote:
> Kirk McDonald wrote:
>> Janice Caron wrote:
>>>> I dont know even what signature it will have, how to distinguish such
>>>> uses:
>>>> c[1, 2..3]
>>>> c[1..2,3]
>>>
>>>
>>> Just a suggestion, but the signature could be
>>>
>>> opSlice(int[] ...)
>>>
>>> where the passed array always had an even number of parameters, and
>>> non-slice parameters get passed as the tuple n, n+1. In that case,
>>> your two cases would be distinguished as [ 1, 2, 2, 3 ] and [ 1, 2, 3,
>>> 4 ] (since 1 is equivalent to 1..2, and 3 is equivalent to 3..4).
>>>
>>> Only works for ints, but hey! Better than nothing.
>>
>> If I may wax Pythonic, there is a better way: Slice objects. Take the 
>> following Python code:
>>
>> class C(object):
>>     def __getitem__(self, i):
>>         return i
>>
>> __getitem__ is roughly the equivalent of opIndex:
>>
>>  >>> c = C()
>>  >>> c[10]
>> 10
>>
>> However, it handles slicing, as well:
>>
>>  >>> c[2:10]
>> slice(2, 10, None)
>>  >>> c[1:5:2]
>> slice(1, 5, 2)
>>
>> Slices in Python have two or three items in them. The first two are 
>> the start and stop indices, which work just like in D. The third is an 
>> optional "step". If you set it to (e.g.) 2, you would get every other 
>> item. As the above code shows, it defaults to None.
>>
>> The slice object is very simple, and has three attributes of note, 
>> start, stop, and step, which are the values passed to the slice.
>>
>> If I may make up some syntax, we could invent a new "slice" type in D. 
>> I am admittedly not very good at making up syntax, but maybe something 
>> like this:
>>
>> alias void[int..int] slice; // a slice from an int to an int
>>
>> (A better keyword than "void" might be thought of.) You could then 
>> declare opIndex like this:
>>
>> class C {
>>     int[] arr;
>>     int opIndex(slice s) {
>>            return arr[s.start..s.stop];
>>         // or just:
>>         return arr[s];
>>     }
>> }
>>
>> The examples mentioned previously become easy as pie. These:
>>
>> c[1, 2..3]
>> c[1..2, 3]
>>
>> Would require the following opIndex methods:
>>
>> int opIndex(int, slice);
>> int opIndex(slice, int);
>>
>> opSlice would, therefore, become entirely obsolete, unless I am 
>> missing some edge-case or other.
>>
>> This is possibly a little wild and crazy. I feel the basic idea is 
>> sound, however. What do other people think?
> 
> I fully agree and have proposed the same more than once. What I have 
> been doing is something that would also handle $ properly. See attached 
> file.
> 
> The class template code for opIndex then need to handle arguments of
> types int, End, EndRel, EndMod, FullRange, Range, EndRange, EndRelRange,
> etc...
> 
> This may all be a bit overkill. But it is a low overhead solution to the 
> problem. And variadic templates make opIndex simple to implement. 
> Template bloat is a problem though.
> 

I fully agree too.  Some sort of slice object would make writing and 
using multi-dim array classes much easier.

--bb



More information about the Digitalmars-d mailing list