Russel Winder:

> Perhaps this needs review.  All modern language now have this as an
> integral way of describing a sequence of values.

We have discussed about this not too much time ago. See the enhancement request:
http://d.puremagic.com/issues/show_bug.cgi?id=5395

D language design is too much un-orthogonal about this, and I'd like to see 
this situation improved.

Currently there are several separated syntaxes and means to specify an interval:

1) foreach interval syntax, no stride allowed and the interval is open on the 
right:

foreach (i; 0 .. 100)


2) Using iota, a badly named range, for intervals open on the right, it 
supports an optional stride:

foreach (i; iota(100))


But empty intervals have different semantics. This runs with no errors, the 
foreach doesn't loop:

void main() {
    foreach (i; 0 .. -1) {}
}

While this raises an exception (Enforcement failed):

import std.range;
void main() {
    foreach (i; iota(0, -1)) {}
}


3) The switch range syntax, it uses two dots still, it's closed on the right:

import std.range;
void main() {
    char c = 'z';
    bool good;
    switch (c) {
        case 'a': .. case 'z':
            good = true;
            break;
        default:
            good = false;
            break;
    }
    assert(good);
}


4) Array slice syntax, it allows empty intervals, and it's open on the right, 
it uses two dots still (and it's not saturating as the Python one, so you must 
be careful with the values of your extrema):

array[1 .. 100]


5) User-defined slice syntax gets converted in a pair of size_t values, instead 
of something like a iota():

int opSlice(size_t x, size_t y);


I'd like built-in first-class interval syntax, to remove some of those special 
cases. opSlice() may return a value that's a slice, the foreach special 
interval syntax may be just removed, just as the switch interval syntax. The 
iota() needs to behave like a slice when it's empty, and not produce an error.

Bye,
bearophile

Reply via email to