www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - rationale for opSlice, opSliceAssign, vs a..b being syntax suger for

reply Timothee Cour <thelastmammoth gmail.com> writes:
Currently x[a...b] calls opSlice(a,b);

This has several drawbacks:

* it breaks _orthogonality_ of features: opIndex should work with
everything (indexes, slices), whereas now we're having an opSliceIndex
that works on slices and opIndex that works on non-slices.

* one can't have multiple slicing / indexing for multiple dimensions, eg:

x[a..b,c..d]
x[a..b,c]
etc.

* it makes it hard to forward slicing arguments across function calls, eg:
auto do_slicing(T)(T slice){
  return x[slice] + y[slice];
}
do_slicing(1..2);

* it makes it hard to support future slicing functionality such as stride, eg:
x[begin..end:stride]

--------
My current workaround in my multidimensional array library is to use a
proxy for slices, eg:
x[R(1,2), 3]
x[a, R(), R(a,b), R(10,$), R(a,b,s)] //exaggerating, just to show the
different options

But those would benefit from syntactic sugar as:
x[1..2, 3]
x[a, .. , a..b, 10..$, a..b:s]
which is easier to read. (the second empty ".." is questionable;
matlab's ":" seems good too).

--------
So my question is:
why can't "a..b" be syntax sugar for a struct, as follows:

Slice(T){
  T begin;
  T end;
}
auto slice(T begin, T end){
  return Slice(begin,end);
}

SliceStride(T,T2){
  T begin;
  T end;
  T2 stride;
}

auto slice(T begin, T end, T stride){
  return SliceStride(begin,end,stride);
}

auto mySlice=10..12; // syntax sugar to call slice(10,12);
auto mySlice=10..12:-2; // syntax sugar to call slice(10,12,-2);

Now making generic code in libraries is trivial:
auto opIndex(T1, T2)(T1 a1, T2 a2){
static if(isSlice!T1){...} else {...}
static if(isSlice!T2){...} else {...}
}

Also, compiler should be able to optimize out the underlying slice
object constructions, so it'd be exactly as efficient as current
scheme.

Same thing goes to opSliceAssign.

Thanks for your feedback,
Timothee.
Apr 06 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Timothee Cour:

 * it breaks _orthogonality_ of features: opIndex should work 
 with
 everything (indexes, slices), whereas now we're having an 
 opSliceIndex
 that works on slices and opIndex that works on non-slices.
Don has discussed about this more than one time. Generally I think there is space for improvements in the D design. If you want bring this topic in the main D newsgroup, but keep in mind this was already discussed one or more times.
 * it makes it hard to support future slicing functionality such 
 as stride, eg:
 x[begin..end:stride]
I think a stride is important.
 Also, compiler should be able to optimize out the underlying 
 slice object constructions,
If the slice is a small struct, it's about as efficient as normal arguments. Bye, bearophile
Apr 06 2013