Foreach Range Statement

Bill Baxter dnewsgroup at billbaxter.com
Mon Jul 23 01:22:15 PDT 2007


Don Clugston 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..$)
> 
> I don't think it make sense to have mixed type ranges. The normal 
> promotion rules should apply. However...
> 
> Floating-point ranges are tricky. Should they be open-ended, or 
> closed-ended? 

Both Matlab and Numpy have floating point ranges.   Matlab ranges are 
always inclusive, so 1:2.1:7.3 gives you 1.0, 3.1, 5.2, 7.3.  Python 
ranges are always non-inclusive, so it gives you 1.0,3.1,5.2.

> Consider
> -real.infinity..real.infinity
> Are the infinities part of the range? If not, how do you specify a range 
> which includes infinity?

Does it matter that much?  I suppose it would be cool if it did 
something really consistent, but Numpy just craps out and gives you an 
empty list, and Matlab raises an error "Maximum variable size allowed by 
the program is exceeded".

> I think the convention "first_element .. last_element+1" cannot be 
> extended to negative and floating-point numbers without creating an 
> inconsistency. Which is quite unfortunate.

In Python the last_element..first_element inclusive case is handled by 
omissions.
   10:0:-1  --- 10 downto 1, inclusive -- doesn't include 0
   10::-1 --- 10 downto last one - includes 0

For D I guess that might become
    10..$:-1
but $ would have to become something context sensitive, rather than just 
a synonym for .length.  Which I guess is the same as saying you'd have 
to introduce an inconsistency, or at least a less strict form of 
consistency, to the interpretation of $.

--bb



More information about the Digitalmars-d mailing list