D2 Short list -- opSlice
Denis Koroskin
2korden at gmail.com
Thu Nov 19 01:03:39 PST 2009
On Thu, 19 Nov 2009 11:53:51 +0300, Don <nospam at nospam.com> wrote:
> Andrei Alexandrescu wrote:
>> We're entering the finale of D2 and I want to keep a short list of
>> things that must be done and integrated in the release. It is clearly
>> understood by all of us that there are many things that could and
>> probably should be done.
>> 1. Currently Walter and Don are diligently fixing the problems marked
>> on the current manuscript.
>> 2. User-defined operators must be revamped.
>
> Should opIndex and opSlice be merged?
> This would be simpler, and would allow multi-dimensional slicing.
> Probably the simplest way to do this would be to use fixed length arrays
> of length 2 for slices.
> So, for example, if the indices are integers, then
> opIndex(int x) { } is the 1-D index, and
> opIndex(int[2] x) {} is a slice from x[0] to x[1],
> which exactly corresponding to the current opSlice(x[0]..x[1]).
>
> Since fixed-length arrays are now passed by value (yay!) this would be
> just as efficient as the current method. It'd be simple to implement.
>
> Downsides: (1) Arguably not terribly intuitive.
> (2) This would not let you have a slicing from A..A, while
> simultaneously allowing indexing by A[2]. But I don't think that makes
> sense anyway -- what would $ return? (Note that it doesn't stop you from
> having indexes of type A[2], and slice from A[2]..A[2], which might be
> important for containers of 2D vectors. It's only the case where
> indexing and slicing are different types, which is prohibited).
>
> This is the only solution I have which doesn't introducing more coupling
> between the language and standard library.
> Another possible solution is to define a special Slice struct in
> std.object; downside is that it creates yet another pseudo-keyword.
>
> A third solution would be to use tuples; currently I think it's
> impossible, but if tuple auto-flattening is removed there may be a
> chance. Even so, it might be a little clumsy to use.
>
> A fourth solution is to retain the status quo, and not provide the
> multi-dimensional slicing feature <g>. This is actually about the same
> amount of work as option (1), since opDollar would need to work for
> opSlice (I only implemented it for opIndex).
I'd like for a..b to be auto-magically rewritten into range(a, b). This
way you can distinguish between indexing and slicing:
struct Range
{
T lower, upper;
// front, back, popFront, popBack, empty
}
Range!(T) range(T)(T lower, T upper) {
return Range!(T)(lower, upper);
}
auto opIndex(Range!(int) range) { // corresponds to foo[a..b];
}
auto opIndex(int index1, int index2) { // corresponds to foo[a, b];
}
This will also get rid of a special case inside foreach:
foreach (i; a..b) {
}
since a..b will be converted into a range, generic rules would apply to it.
More information about the Digitalmars-d
mailing list