Foreach Range Statement
Bill Baxter
dnewsgroup at billbaxter.com
Mon Jul 23 01:40:10 PDT 2007
Reiner Pope wrote:
> 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....
Let's just call it __slice. I think __traits is lonely.
--bb
More information about the Digitalmars-d
mailing list