Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
June 02, 2011 No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
import std.range; void main() { auto arr = [1, 2, 3, 4, 5, 6, 7, 8]; auto foo = cycle(arr); // nope foreach (int index, int val; foo) { } // nope foreach (int index, int val; take(foo, 5)) { } // ok foreach (int index, int val; take(arr, 5)) { } } Is this because cycle is an infinite range, and index might overflow? I could understand that. But I think if I use take() then there should be no problem with overflows. It still doesn't work though. |
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic:
> Is this because cycle is an infinite range, and index might overflow?
The cause is different: cycle is a range, and they don't define an counter variable. With opApply sometimes you define the counter too. The compiler doesn't create a counter variable for free.
Bye,
bearophile
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Thu, 02 Jun 2011 14:17:26 -0400, Andrej Mitrovic <none@none.none> wrote:
> import std.range;
>
> void main()
> {
> auto arr = [1, 2, 3, 4, 5, 6, 7, 8];
> auto foo = cycle(arr);
> // nope
> foreach (int index, int val; foo)
> {
> }
> // nope
> foreach (int index, int val; take(foo, 5))
> {
> }
> // ok
> foreach (int index, int val; take(arr, 5))
> {
> }
> }
>
> Is this because cycle is an infinite range, and index might overflow? I could understand that. But I think if I use take() then there should be no problem with overflows. It still doesn't work though.
As bearophile says, there is no standard for the index portion of a range (except for slices, which also happen to be ranges) during foreach.
The reason take(arr, 5) works is because it translates to arr[0..5] which is a slice.
-Steve
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Well actually all I wanted was a counter variable. I can put the thing in a for loop or while loop, but I thought that a counter variable is something that the compiler can always add without too much thinking. I guess things aren't so simple. |
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Thu, 02 Jun 2011 17:38:38 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Well actually all I wanted was a counter variable. I can put the thing
> in a for loop or while loop, but I thought that a counter variable is
> something that the compiler can always add without too much thinking.
>
> I guess things aren't so simple.
In fact, if indexes for ranges were implemented during foreach, it would *have* to be this way. An explanation:
Note that foreach(x; range) translates to:
auto _r = range;
for(; !_r.empty; _r.popNext())
{
auto x = _r.front;
...
}
So think about this for a second, if you wanted to add an index variable, what is the index of _r.front()? In the case of simple arrays, it's *always* 0! So the index would have to be tracked by the loop, not by the range.
But we'd also need a way to override this. For instance, a range on an associative array, the index is not a sequential integer series starting at 0.
So I'm not sure how this would be solved, but it's definitely complicated.
Note that opApply solves this beautifully, since opApply has it's own temporary scope where you can track anything you want.
-Steve
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Thu, 02 Jun 2011 17:38:38 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> Well actually all I wanted was a counter variable. I can put the thing
> in a for loop or while loop, but I thought that a counter variable is
> something that the compiler can always add without too much thinking.
Also, BTW, you can still do this with a foreach loop:
size_t idx = ~0; //hacky, I know.
foreach(x; range)
{
++idx;
...
}
-Steve
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 6/2/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> On Thu, 02 Jun 2011 17:38:38 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>
>> Well actually all I wanted was a counter variable. I can put the thing in a for loop or while loop, but I thought that a counter variable is something that the compiler can always add without too much thinking.
>
> Also, BTW, you can still do this with a foreach loop:
>
> size_t idx = ~0; //hacky, I know.
> foreach(x; range)
> {
> ++idx;
> ...
> }
>
> -Steve
>
Heh, I thought I'd never see a use-case for an overflow. Btw., did ya know you can cram more expressions before the range?
size_t idx;
foreach(x; idx = ~0, [1, 2, 3])
{
writeln(++idx);
}
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Thu, 02 Jun 2011 18:01:21 -0400, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 6/2/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>> On Thu, 02 Jun 2011 17:38:38 -0400, Andrej Mitrovic
>> <andrej.mitrovich@gmail.com> wrote:
>>
>>> Well actually all I wanted was a counter variable. I can put the thing
>>> in a for loop or while loop, but I thought that a counter variable is
>>> something that the compiler can always add without too much thinking.
>>
>> Also, BTW, you can still do this with a foreach loop:
>>
>> size_t idx = ~0; //hacky, I know.
>> foreach(x; range)
>> {
>> ++idx;
>> ...
>> }
>>
>> -Steve
>>
>
> Heh, I thought I'd never see a use-case for an overflow. Btw., did ya
> know you can cram more expressions before the range?
>
> size_t idx;
> foreach(x; idx = ~0, [1, 2, 3])
> {
> writeln(++idx);
> }
That is so... so evil...
I mean the plethora of commas, *shudder*.
:)
-Steve
|
June 02, 2011 Re: No index for cycle ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer: > So I'm not sure how this would be solved, but it's definitely complicated. To solve this problem Python uses the enumerate function: >>> for c in "abc": ... print c ... a b c >>> for i,c in enumerate("abc"): ... print i, c ... 0 a 1 b 2 c In D it's easy to create something similar to enumerate, that yields tuple(index,item). But in D there is no syntax sugar for tuple unpacking yet, so here the index management becomes less nice. I suggest to add enumerate to std.range, see: http://d.puremagic.com/issues/show_bug.cgi?id=5550 Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation