digitalmars.D.learn - No index for cycle ranges
- Andrej Mitrovic (22/22) Jun 02 2011 import std.range;
- bearophile (4/5) Jun 02 2011 The cause is different: cycle is a range, and they don't define an count...
- Steven Schveighoffer (6/27) Jun 02 2011 As bearophile says, there is no standard for the index portion of a rang...
- Andrej Mitrovic (4/4) Jun 02 2011 Well actually all I wanted was a counter variable. I can put the thing
- Steven Schveighoffer (22/26) Jun 02 2011 In fact, if indexes for ranges were implemented during foreach, it would...
- bearophile (17/20) Jun 02 2011 ... print c
- Steven Schveighoffer (10/13) Jun 02 2011 Also, BTW, you can still do this with a foreach loop:
- Andrej Mitrovic (8/21) Jun 02 2011 Heh, I thought I'd never see a use-case for an overflow. Btw., did ya
- Steven Schveighoffer (6/32) Jun 02 2011 That is so... so evil...
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.
Jun 02 2011
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
Jun 02 2011
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
Jun 02 2011
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.
Jun 02 2011
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
Jun 02 2011
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:... print c ... a b cfor c in "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, bearophilefor i,c in enumerate("abc"):
Jun 02 2011
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
Jun 02 2011
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: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); }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
Jun 02 2011
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:That is so... so evil... I mean the plethora of commas, *shudder*. :) -SteveOn Thu, 02 Jun 2011 17:38:38 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote: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); }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
Jun 02 2011