D - Cool foreach loops
- Bill Cox (33/33) Feb 03 2003 Hi.
- Daniel Yokomiso (6/39) Feb 04 2003 It looks very similar to Sather iterators, but less powerful, because it...
- Bill Cox (11/63) Feb 12 2003 Hi, Daniel.
- Daniel Yokomiso (81/144) Feb 13 2003 Hi,
Hi. I've been playing with foreach itterator syntax a bit. This mechanism is complex, but very nice to use. If it's not too complex to implement, I think it might be a nice enhancement to D. Here's how it works. In a container class, or any class that needs an itterator over children, define a loop function. Here's an example for directed graphs: class Node { Edge firstIn, firstOut; // This itterates through in edges loop inEdges(Edge edge) { for(edge = firstIn; edge != null; edge = edge.nextInEdge) { doloop; } } // This itterates through out edges loop outEdges(Edge edge) { for(edge = firstOut; edge != null; edge = edge.nextOutEdge) { doloop; } } // This itterates through all edges loop edges(Edge edge) { foreach(inEdges, edge) { doloop; } foreach(outEdges, edge) { doloop; } } } The foreach loops specify a loop function, and a loop variable. The compiler can inline the loop functions to generate the expected code Bill
Feb 03 2003
In article <b1nrjp$1032$1 digitaldaemon.com>, Bill Cox says...Hi. I've been playing with foreach itterator syntax a bit. This mechanism is complex, but very nice to use. If it's not too complex to implement, I think it might be a nice enhancement to D. Here's how it works. In a container class, or any class that needs an itterator over children, define a loop function. Here's an example for directed graphs: class Node { Edge firstIn, firstOut; // This itterates through in edges loop inEdges(Edge edge) { for(edge = firstIn; edge != null; edge = edge.nextInEdge) { doloop; } } // This itterates through out edges loop outEdges(Edge edge) { for(edge = firstOut; edge != null; edge = edge.nextOutEdge) { doloop; } } // This itterates through all edges loop edges(Edge edge) { foreach(inEdges, edge) { doloop; } foreach(outEdges, edge) { doloop; } } } The foreach loops specify a loop function, and a loop variable. The compiler can inline the loop functions to generate the expected code BillIt looks very similar to Sather iterators, but less powerful, because it can iterate only over one iterator. There's some useful info at: http://www.icsi.berkeley.edu/~sather/Documentation/IteratorTutorial/ http://www.icsi.berkeley.edu/~sather/index.html http://www.cs.waikato.ac.nz/sather/
Feb 04 2003
Hi, Daniel. The Sather itterators seem less powerful. With the loop functions illustrated below, it's possible to eliminate one of the most common need for function pointers in C: passing callbacks to complex data traversal routines. With this itterator syntax, you could create itterators that traverse binary trees, doing the loop body for each node. The code is easy to write and read. Doing this in Sather is comparitively ugly, and less efficient. Bill Daniel Yokomiso wrote:In article <b1nrjp$1032$1 digitaldaemon.com>, Bill Cox says...Hi. I've been playing with foreach itterator syntax a bit. This mechanism is complex, but very nice to use. If it's not too complex to implement, I think it might be a nice enhancement to D. Here's how it works. In a container class, or any class that needs an itterator over children, define a loop function. Here's an example for directed graphs: class Node { Edge firstIn, firstOut; // This itterates through in edges loop inEdges(Edge edge) { for(edge = firstIn; edge != null; edge = edge.nextInEdge) { doloop; } } // This itterates through out edges loop outEdges(Edge edge) { for(edge = firstOut; edge != null; edge = edge.nextOutEdge) { doloop; } } // This itterates through all edges loop edges(Edge edge) { foreach(inEdges, edge) { doloop; } foreach(outEdges, edge) { doloop; } } } The foreach loops specify a loop function, and a loop variable. The compiler can inline the loop functions to generate the expected code BillIt looks very similar to Sather iterators, but less powerful, because it can iterate only over one iterator. There's some useful info at: http://www.icsi.berkeley.edu/~sather/Documentation/IteratorTutorial/ http://www.icsi.berkeley.edu/~sather/index.html http://www.cs.waikato.ac.nz/sather/
Feb 12 2003
Hi, Comments embedded: In article <3E4A81F1.6080300 viasic.com>, Bill Cox says...Hi, Daniel. The Sather itterators seem less powerful. With the loop functions illustrated below, it's possible to eliminate one of the most common need for function pointers in C: passing callbacks to complex data traversal routines. With this itterator syntax, you could create itterators that traverse binary trees, doing the loop body for each node. The code is easy to write and read. Doing this in Sather is comparitively ugly, and less efficient. BillI don't understand your remarks about Sather-like iterators being "less powerful" or "ugly". Here's your code written using Sather-like iterating constructs (I'm mixing Sather and D syntax): class Node { Edge firstIn, firstOut; // note that ! marks a method as an iterator Edge inEdges!() { Edge edge = firstIn; // while isn't a primitive but a iterator too loop while!(edge != null); yield edge; edge = edge.nextInEdge end } Edge outEdges!() { Edge edge = firstOut; loop while!(edge != null); yield edge; edge = edge.nextOutEdge end } Edge edges!() { loop yield inEdges!(); end loop yield outEdges!(); end } } Iterators can be used to yield values of series: int fibs!() { int a = 0; int b = 1; loop yield a; (a, b) = (b, a + b); // tuple construction/deconstruction is nice ;-) end } They can also be combined in several ways. More than one iterator can be used in the same loop, and the first to end will terminate the loop. There's also input iterators, like: class List { Object get!() { int i = 0; loop while!( i < size()); yield get(i); i++; end } void set!(Object value) { int i = 0; loop while!( i < size()); set(i, value); yield; i++; end } void copy(List other) { loop set!(other.get!()); // ends when either get! or set! quits end } void copyFiltering(List other, bit (*predicate)(Object)) { loop Object value = other.get!(); if (predicate(value)) { set!(value); // not all iterators in the loop // are called every iteration } end } } Your foreach syntax is very similar to CLU, which was the base for Sather iterators, but they went beyond it. There are lots of good iterator examples available and AFAIK they can be compiled to efficient assembly.Daniel Yokomiso wrote:Best regards, Daniel Yokomiso.In article <b1nrjp$1032$1 digitaldaemon.com>, Bill Cox says...Hi. I've been playing with foreach itterator syntax a bit. This mechanism is complex, but very nice to use. If it's not too complex to implement, I think it might be a nice enhancement to D. Here's how it works. In a container class, or any class that needs an itterator over children, define a loop function. Here's an example for directed graphs: class Node { Edge firstIn, firstOut; // This itterates through in edges loop inEdges(Edge edge) { for(edge = firstIn; edge != null; edge = edge.nextInEdge) { doloop; } } // This itterates through out edges loop outEdges(Edge edge) { for(edge = firstOut; edge != null; edge = edge.nextOutEdge) { doloop; } } // This itterates through all edges loop edges(Edge edge) { foreach(inEdges, edge) { doloop; } foreach(outEdges, edge) { doloop; } } } The foreach loops specify a loop function, and a loop variable. The compiler can inline the loop functions to generate the expected code BillIt looks very similar to Sather iterators, but less powerful, because it can iterate only over one iterator. There's some useful info at: http://www.icsi.berkeley.edu/~sather/Documentation/IteratorTutorial/ http://www.icsi.berkeley.edu/~sather/index.html http://www.cs.waikato.ac.nz/sather/
Feb 13 2003