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