www.digitalmars.com         C & C++   DMDScript  

D - Multiple parameter foreach

reply Patrick Down <pat codemoon.com> writes:
Walter I really like the new foreach statement.
I think it would be nice to be able to have
multiple iteration parameters for struct and classes.

For example:

foreach(Type1 a; Type2 b; object)
{
}

Where object has an apply fuction like this:

int apply(int delegate(inout Type1, inout Type2) dg);
Sep 11 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Patrick Down" <pat codemoon.com> wrote in message
news:Xns93F3E774467D7patcodemooncom 63.105.9.61...
 Walter I really like the new foreach statement.
 I think it would be nice to be able to have
 multiple iteration parameters for struct and classes.

 For example:

 foreach(Type1 a; Type2 b; object)
 {
 }

 Where object has an apply fuction like this:

 int apply(int delegate(inout Type1, inout Type2) dg);

Hmm. That is an interesting idea. It would parse easier if the object came first: foreach(object; Type1 a; Type2 b) or perhaps: foreach(Type1 a, Type2 b; object) note the use of , instead of ;
Sep 11 2003
next sibling parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:bjrq5h$2b8j$1 digitaldaemon.com...
 "Patrick Down" <pat codemoon.com> wrote in message
 news:Xns93F3E774467D7patcodemooncom 63.105.9.61...
 Walter I really like the new foreach statement.
 I think it would be nice to be able to have
 multiple iteration parameters for struct and classes.

 For example:

 foreach(Type1 a; Type2 b; object)
 {
 }

 Where object has an apply fuction like this:

 int apply(int delegate(inout Type1, inout Type2) dg);

Hmm. That is an interesting idea. It would parse easier if the object came first: foreach(object; Type1 a; Type2 b) or perhaps: foreach(Type1 a, Type2 b; object) note the use of , instead of ;

Another question about foreach. It doesn't handle iterating over multiple containers, does it? I mean, can we compare two lists for equivalence? bool equivalent(IntList xs, IntList ys) { if (xs.count() == ys.count()) { foreach(int x; xs; int y; ys) { if (x != y) { return false; } } return true; } else { return false; } } I know this syntax doesn't work but this kind should be allowed, or else we'll need to provide external iterators for our classes. Best regards, Daniel Yokomiso. "If there are really men with white skin in big ships sailing across the Great Water from the east, why haven't they sent us smoke signals? The believers in the White Gods are just flakos who don't understand the basic principles of witch doctoring. We have nothing to fear from them." - Steve Franklin at /. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.514 / Virus Database: 312 - Release Date: 29/8/2003
Sep 12 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:bjs7lf$2v4v$1 digitaldaemon.com...
 Another question about foreach. It doesn't handle iterating over multiple
 containers, does it? I mean, can we compare two lists for equivalence?

 bool equivalent(IntList xs, IntList ys) {
     if (xs.count() == ys.count()) {
         foreach(int x; xs; int y; ys) {
             if (x != y) {
                 return false;
             }
         }
         return true;
     } else {
         return false;
     }
 }

 I know this syntax doesn't work but this kind should be allowed, or else
 we'll need to provide external iterators for our classes.

Unfortunately, I don't see how that can work with the way foreach is done. Doing equivalence will probably have to be a member function of IntList.
Sep 12 2003
parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:bjsqg7$mf8$1 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:bjs7lf$2v4v$1 digitaldaemon.com...
 Another question about foreach. It doesn't handle iterating over


 containers, does it? I mean, can we compare two lists for equivalence?

 bool equivalent(IntList xs, IntList ys) {
     if (xs.count() == ys.count()) {
         foreach(int x; xs; int y; ys) {
             if (x != y) {
                 return false;
             }
         }
         return true;
     } else {
         return false;
     }
 }

 I know this syntax doesn't work but this kind should be allowed, or else
 we'll need to provide external iterators for our classes.

Unfortunately, I don't see how that can work with the way foreach is done. Doing equivalence will probably have to be a member function of IntList.

There are infinite (or some really big number) of possible operations involving two or more containers, so making them all member functions isn't possible. I guess we'll still have to provide external iterators. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.516 / Virus Database: 313 - Release Date: 1/9/2003
Sep 13 2003
prev sibling parent reply Patrick Down <Patrick_member pathlink.com> writes:
In article <bjs7lf$2v4v$1 digitaldaemon.com>, Daniel Yokomiso says...

Another question about foreach. It doesn't handle iterating over multiple
containers, does it? I mean, can we compare two lists for equivalence?


bool equivalent(IntList xs, IntList ys) {
    if (xs.count() == ys.count()) {
        foreach(int x; xs; int y; ys) {
            if (x != y) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}

Not quite as elegant... template PairArray(Type1,Type2) { struct PairIter { Type1[] arr1; Type2[] arr2; int apply(int delegate(inout Type1, inout Type2) dg) { int rtn = 0; for(int i = 0; i < arr1.length; ++i) { rtn = dg(arr1[i],arr[2]); if(rtn) break; } return rtn; } } PairIter PairUp(Type1[] arr1, Type2[] arr2) { PairIter rtn; rtn.arr1 = arr1; rtn.arr2 = arr2; return rtn; } } bool equivalent(IntList xs, IntList ys) { if (xs.count() == ys.count()) { foreach(int x, int y; instance PairArray(int,int).PairUp(xs,ys)) { if (x != y) { return false; } } return true; } else { return false; } }
Sep 12 2003
parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Patrick Down" <Patrick_member pathlink.com> escreveu na mensagem
news:bjss2n$oqk$1 digitaldaemon.com...
 In article <bjs7lf$2v4v$1 digitaldaemon.com>, Daniel Yokomiso says...

Another question about foreach. It doesn't handle iterating over multiple
containers, does it? I mean, can we compare two lists for equivalence?


bool equivalent(IntList xs, IntList ys) {
    if (xs.count() == ys.count()) {
        foreach(int x; xs; int y; ys) {
            if (x != y) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}

Not quite as elegant... template PairArray(Type1,Type2) { struct PairIter { Type1[] arr1; Type2[] arr2; int apply(int delegate(inout Type1, inout Type2) dg) { int rtn = 0; for(int i = 0; i < arr1.length; ++i) { rtn = dg(arr1[i],arr[2]); if(rtn) break; } return rtn; } } PairIter PairUp(Type1[] arr1, Type2[] arr2) { PairIter rtn; rtn.arr1 = arr1; rtn.arr2 = arr2; return rtn; } } bool equivalent(IntList xs, IntList ys) { if (xs.count() == ys.count()) { foreach(int x, int y; instance PairArray(int,int).PairUp(xs,ys)) { if (x != y) { return false; } } return true; } else { return false; } }

Yes, but your solution doesn't work with non-array containers, unless they provide external iteration. If we have a "BinaryTree" and a "Heap" each with a "apply" method, it's useless. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.516 / Virus Database: 313 - Release Date: 1/9/2003
Sep 13 2003
parent reply Patrick Down <pat codemoon.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in
news:bk06c0$2c86$1 digitaldaemon.com: 

 
 Yes, but your solution doesn't work with non-array containers, unless
 they provide external iteration. If we have a "BinaryTree" and a
 "Heap" each with a "apply" method, it's useless.

Yes, but how would Walter implement it? The apply fuction drives the iteration so how would two or more apply fuctions supply parameters to the delegate callback? It would have to be done with coroutines.
Sep 13 2003
parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Patrick Down" <pat codemoon.com> escreveu na mensagem
news:Xns93F5E5AAE8BCDpatcodemooncom 63.105.9.61...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in
 news:bk06c0$2c86$1 digitaldaemon.com:

 Yes, but your solution doesn't work with non-array containers, unless
 they provide external iteration. If we have a "BinaryTree" and a
 "Heap" each with a "apply" method, it's useless.

Yes, but how would Walter implement it? The apply fuction drives the iteration so how would two or more apply fuctions supply parameters to the delegate callback? It would have to be done with coroutines.

He's the compiler guy, I'm just the annoying person that keeps asking questions ;) Seriously coroutines is the most simple solution, with a smart compiler most iterator calls can be inlined reducing the performance penalty. Other solution is go the Python or C# way to have a special syntax to create iterators and make them heap objects. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 12/9/2003
Sep 15 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:bk46us$1mn5$1 digitaldaemon.com...
 Seriously coroutines is the most simple solution, with a smart compiler

 iterator calls can be inlined reducing the performance penalty. Other
 solution is go the Python or C# way to have a special syntax to create
 iterators and make them heap objects.

I checked into coroutines, and they don't look simple at all to implement :-(
Sep 16 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bk8pnp$pat$2 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:bk46us$1mn5$1 digitaldaemon.com...
 Seriously coroutines is the most simple solution, with a smart compiler

 iterator calls can be inlined reducing the performance penalty. Other
 solution is go the Python or C# way to have a special syntax to create
 iterators and make them heap objects.

I checked into coroutines, and they don't look simple at all to implement :-(

Are we getting tuples instead, or is this basket as hard as coroutines?
Sep 16 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bk8sgg$t8i$1 digitaldaemon.com...
 Are we getting tuples instead, or is this basket as hard as coroutines?

You ask for at least one new feature every day! <G>
Sep 17 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
"Walter" <walter digitalmars.com> wrote in message
news:bk948l$18uf$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bk8sgg$t8i$1 digitaldaemon.com...
 Are we getting tuples instead, or is this basket as hard as coroutines?

You ask for at least one new feature every day! <G>

Then just give me an old one. Just a property that I can call my own ...
Sep 17 2003
prev sibling next sibling parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:bk8pnp$pat$2 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:bk46us$1mn5$1 digitaldaemon.com...
 Seriously coroutines is the most simple solution, with a smart compiler

 iterator calls can be inlined reducing the performance penalty. Other
 solution is go the Python or C# way to have a special syntax to create
 iterators and make them heap objects.

I checked into coroutines, and they don't look simple at all to implement :-(

Hmmm, coroutines are conceptually simple, but there are some very complex implementations. IIRC the coroutine/iterator scheme of Sather was simple, but would introduce some overhead without optimizations (i.e. iterator inlining). As the Sather is GPL'ed you could look at the source code and/or Sather compiler papers. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.518 / Virus Database: 316 - Release Date: 12/9/2003
Sep 17 2003
prev sibling parent Karl Bochert <kbochert copper.net> writes:
On Tue, 16 Sep 2003 22:00:12 -0700, "Walter" <walter digitalmars.com> wrote:
 
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:bk46us$1mn5$1 digitaldaemon.com...
 Seriously coroutines is the most simple solution, with a smart compiler

 iterator calls can be inlined reducing the performance penalty. Other
 solution is go the Python or C# way to have a special syntax to create
 iterators and make them heap objects.

I checked into coroutines, and they don't look simple at all to implement :-(

I suspect that my definition of couroutine is different than yours, or I am overlooking something important.
Sep 17 2003
prev sibling parent Patrick Down <pat codemoon.com> writes:
"Walter" <walter digitalmars.com> wrote in
news:bjrq5h$2b8j$1 digitaldaemon.com: 

 "Patrick Down" <pat codemoon.com> wrote in message
 news:Xns93F3E774467D7patcodemooncom 63.105.9.61...
 Walter I really like the new foreach statement.
 I think it would be nice to be able to have
 multiple iteration parameters for struct and classes.

 For example:

 foreach(Type1 a; Type2 b; object)
 {
 }

 Where object has an apply fuction like this:

 int apply(int delegate(inout Type1, inout Type2) dg);

Hmm. That is an interesting idea. It would parse easier if the object came first: foreach(object; Type1 a; Type2 b) or perhaps: foreach(Type1 a, Type2 b; object)

I like this one better.
Sep 12 2003
prev sibling parent Benji Smith <dlanguage xxagg.com> writes:
In article <Xns93F3E774467D7patcodemooncom 63.105.9.61>, Patrick Down says...
foreach(Type1 a; Type2 b; object)
{
}

Where object has an apply fuction like this:

I don't understand why we would need this. Why not use the following: foreach (Object myObject; myContainer) { Type1 a = myObject.a; Type2 b = myObject.b; } --Benji Smith
Sep 12 2003