foreach range with index

Luís Marques via Digitalmars-d digitalmars-d at puremagic.com
Wed Jun 14 08:42:51 PDT 2017


On Wednesday, 14 June 2017 at 14:35:32 UTC, Steven Schveighoffer 
wrote:
> What I'd rather see is a better mechanism for ranges (or things 
> that provide ranges) to hook the foreach syntax to allow better 
> control and power from ranges without using traditional opApply.
>
> For example, if we had:
>
> foreach(size_t a, b; x)
>
> translates to:
>
> for(auto _context = x.opApply!(size_t, void); !context.empty; 
> _context.popFront)
> {
>    auto (a, b) = _context.front; // the way it works now with 
> tuples, don't think there's a real syntax for this.
>    ...
> }

An approach like that seems fine to me. In any case, why do it in 
exclusion of a foreach-generated index? Imagine that I define an 
input range. Can we assume that range.front is *conceptually* 
equivalent to range[0], even if the range doesn't define random 
access?  Because if we can, then, if the range doesn't define the 
new opApply or whatever, why not allow foreach to generate the 
index?

> Yes, foreach could be augmented to do that. However, this is 
> essentially a way to implement enumerate without the 
> .enumerate, and nothing more. It's not a lot of added benefit 
> IMO.

Consider this case. You create a prototype where foo is a slice. 
Then you start improving the code and foo becomes a range. In 
your code you have several places that use foo with foreach, and 
several places where it is used directly. If you define the new 
foo as newRangeFoo.enumerate, then the several foreach work 
automatically, but the other uses don't because they have to be 
changed to foo.value; if you do it the other way around, the 
direct uses work automatically but the foreach all have to be 
changed from foo to foo.enumerate. Thus you have lost a lot of 
the code plasticity. If the foreach statement generated the 
indices then it would work automatically.

This could also be solved by the range defining your new version 
of opApply and foreach understanding that. Assuming that we can 
wrap old ranges (e.g. from a library you don't want to change) 
with that opApply, I would be fine with that solution as long as 
this is something that actually goes forward. I'm just afraid 
this is something that will linger because it's a more difficult 
design decision, while having foreach support index generation 
seems like a more self contained solution that could be agreed 
upon and implemented quickly.


More information about the Digitalmars-d mailing list