Foreach Range Statement

Reiner Pope some at address.com
Mon Jul 23 02:42:01 PDT 2007


Bill Baxter 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.
> 
> Thanks.  I think Oskar Linde had a nice version too.  I seem to remember 
> thinking there were a few things in his that I should borrow.
> 
>> 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..$)
> 
> Having two different types for it seems odd.  Just plain int.. would 
> make more sense to me.  I really like that 5..1:-1 syntax though!  Was 
> that mentioned before?  Something about all the colons in Pythons range 
> literals always makes me uneasy.  a:b:c -- is that a to c stepping by b? 
>  Or a to b stepping by c?  In Python it's the latter.  In Matlab I think 
> it's the former.  Which is probably why I always feel a little uneasy 
> when I see it.  But a..b:c is much clearer!  Obviously it's from a to b, 
> so c must be a step.  And the colon looking like the two dots stood on 
> end -- lovely.

I never knew about the Python or Matlab syntax. 5..1:-1 is from Norbert 
Nemec's multidimensional array proposal, and it makes so much sense. :)

But I don't know about the declaration syntax of the type. The most 
obvious and the nicest-looking is definitely 'int..int'. But using that 
suggests that 'int..double' should be allowed, which doesn't really make 
much sense, given that operations on ranges will probably be mostly 
indexing, iterating through the range, and testing whether an element is 
contained in that range, each of which require one characteristic type.

So the characteristic type of the range should only be said once. But I 
don't like int.. because of what it implies:

   int..:
   int:  // a stepped range from here to infinity; but it looks like case:
   ..int: // I dunno: reverse iteration?

You really need something to hold the number's place, But nothing comes 
to mind, other than (the ugly) #
    int..#
    int..#:#
    ..int:#

Mind you, I think it allows a nice syntax for what I was grasping in a 
different post with the wacky question-mark syntax (int..int:int?). You 
need to be able to specify which promotions may be done implicitly, and 
with what default values. I think the easiest way is to specify the 
default values as part of the type:

    int..#:1   (a range from lo to hi, with step 1 unless specified)
    int..5:#
    int=3..#   (lo has a default value of 3)

One range, A, could only be implicitly converted to another if it every 
field in A was included in B (so we don't lose information) and all the 
fields in B missing from A have default values (so it's not implicitly 
converted by mistake).


Just my train of thought,

    Reiner



More information about the Digitalmars-d mailing list