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