Foreach Range Statement
Reiner Pope
some at address.com
Mon Jul 23 00:56:20 PDT 2007
Reiner Pope wrote:
> Bill Baxter wrote:
>> Jarrett Billingsley wrote:
>>> "Xinok" <xnknet at gmail.com> wrote in message
>>> news:f80qof$2n0l$1 at digitalmars.com...
>>>
>>>> foreach(i; 0..100)
>>>
>>> This is almost identical to the syntax in MiniD:
>>>
>>> for(i: 0 .. 100)
>>>
>>> It could be done with for or foreach; I just chose for because
>>> normally you use for loops to iterate over ranges of integers.
>>>
>>> You can also come up with a pretty simple short-term solution that'll
>>> be fairly efficient (though not as efficient as if the compiler were
>>> aware of this kind of loop intrinsically) by making a struct 'range'
>>> which has a static opCall to construct a range and an opApply to
>>> iterate over the values, so that it'd look like:
>>>
>>> foreach(i; range(100))
>>>
>>> Which isn't terrible at all.
>>
>> And it has the advantage of being more extensible. And for allowing
>> ranges to be treated as first class entities that can be passed around
>> and manipulated. But no, instead we get another one-trick pony.
>>
>> --bb
> That was my first thought, too.
>
> In the "Array Slice Ranges" thread, several people mentioned first-class
> ranges:
>
> http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=43865
>
> http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=43904
>
> http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=43905
>
> http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=43954
>
>
> Your implementation, Bill, seems to be just right, and gives you foreach
> over ranges for free.
>
> What's wrong with adding that to the language, but templated and with
> nice syntax?
>
> type name literal
> int..int (range of int) 1..5
> int..double (range of int to double) 1..5.0
> int..int:int (stepped range) 5..1:-1
>
> (I'm not sure of the use of mixed-type ranges, but this seems the most
> intuitive syntax. Since most ranges are probably of one type, how about
> allowing a symbol to denote "same type again". Any of the following
> could mean int..int: int..#, int.._, int..$)
>
> As several people have pointed out, this also fixes mixed
> indexing/slicing problems for multi-dimensional arrays.
>
>
>
> Reiner
Oh, and let's throw in another dimension for good measure: :-)
Adding a '?' after the type means it's optional. This means two things:
you can omit the value in literals, and it will be its default value;
and it can be cast to from other range types, so 'int..int' can be
implicitly converted to 'int..int:int?' but not 'int..int:int'. This
gives a use for mixed-type ranges:
typedef size_t step = 1;
struct MyArray(T)
{
...
// returns a slice of the array, with a step of 1 unless specified
MyArray!(T) opIndex(size_t..size_t:step? range)
{
...
}
}
But with # *and* ? being used by slice syntax, it might be using a few
too many symbols for one concept....
Reiner
More information about the Digitalmars-d
mailing list