foreach syntax, std.mixin

dsimcha dsimcha at yahoo.com
Sun Nov 8 12:14:27 PST 2009


== Quote from Bill Baxter (wbaxter at gmail.com)'s article
> On Sun, Nov 8, 2009 at 9:10 AM, dsimcha <dsimcha at yahoo.com> wrote:
> > What are the chances that D gets auto tuple unpacking for foreach loops b
> efore
> > D2 goes gold?  In other words, it would be nice to write:
> >
> > uint[] foo = [1,2,3,4,5];
> > uint[] bar = [6,7,8,9,10];
> >
> > foreach(a, b; zip(foo, bar)) {
> >    // Does what you think it does.
> > }
> Probably obvious, but if added, it should probably work by means of
> .tupleof on the iterated type, rather than by any particular knowledge
> of types used in std.range.  And I guess just public members would be
> included.
> Main down side is that it could introduce ambiguities with explicitly
> specified opApply overloads.  If you have an opApply that takes
> uint,uint already, which gets used?  Or is it an error?  I not sure
> what would be least likely to cause trouble.  One the one hand the
> class author should be able to override the behavior, but on the other
> hand class users will assume that tuple unpacking works and may be
> surprised if it has been overriden to do something different.  So
> either rule -- specifc opApply wins, or it's an error -- seems to have
> an argument for it.
> > Also, how about foreach over ranges with an index variable?  For exampl
> e:
> >
> > foreach(index, elem; chain(foo, bar)) {
> >   // Does what you think it does.
> > }
> This will create too many ambiguities if the tuple unpacking is also
> implemeted, so I'm agaist it:
> foreach(index,elem; zip(arrayOfInts, bar)) {
>     // I don't know what this does
> }
> I think the index variant would better be done as an enumerate()
> function like in python. Which does something like
> zip(iota(1,bar.length),bar).

Enumerate is a great idea.  It's probably much better than requiring every range
struct to mix something in to enable this behavior.  Thanks.

I guess the same thing could be applied to unpack().  Instead of making the range
implementer mixin something to enable this (he/she will probably forget and it
could lead to ambiguities), do it on the caller end.

Makes me wonder why noone thought of this until now, or maybe someone did and I
forgot.  How's:

foreach(fooElem, barElem; unpack(zip(foo, bar))) {}, or:

foreach(i, elem; enumerate(chain(foo, bar))) {} ?




More information about the Digitalmars-d mailing list