On Fri, 2006-09-08 at 10:40 +1000, skaller wrote: > Felix now supports first class iterators, as a special > case of generators. Here is an example:
Here's more elaborate example: ---------------------------------------- #import <flx.flxh> union tree = TEmpty | Leaf of int | Node of tree * tree; var example = Node ( Node ( Leaf 1, Node ( Leaf 2, Leaf 3 ) ) , Node ( Leaf 4, Leaf 5 ) ) ; fun sum: tree->int = | Leaf ?x => x | Node (?l,?r) => sum l + sum r | TEmpty => 0 ; print$ sum example; endl; fun accumulate(it: 1-> int):int= { var x = 0; var v = it(); whilst v != -1 do x += v; v = it(); done; return x; } gen visitor(x:tree) () : int = { var con = match x with | Leaf ?a => { print "visiting leaf "; print a; endl; yield a; return -1; } | Node (?a,?b) => { print "visiting node: left\n"; var it = visitor(a); var v = it(); whilst v != -1 do yield v; v = it(); done; print "visiting node: right\n"; it = visitor(b); v = it(); whilst v != -1 do yield v; v = it(); done; return -1; } | TEmpty => { return -1; } endmatch ; var r = con(); whilst r != -1 do yield r; r = con(); done; return -1; } var it = visitor(example); var res = accumulate(it); print$ res; endl; ------------------------------------ [EMAIL PROTECTED]:/work/felix/svn/felix/felix/trunk$ flx --test --force rd 15 visiting node: left visiting node: left visiting leaf 1 visiting node: right visiting node: left visiting leaf 2 visiting node: right visiting leaf 3 visiting node: right visiting node: left visiting leaf 4 visiting node: right visiting leaf 5 15 ------------------------------------ This example is complicated by the fact that matches return expressions. The expression returned in the visitor is a generator closure. However we can't simply execute it, because the internal state would be lost. Instead, it has to be stored in a variable first. Then we iterate it, yielding each value. The example would be simpler if Felix had a procedural match. [Add to 'todo' list] This shows that despite generators only yielding up one level, not deep within a recursion .. it doesn't matter! Although the whole physical call chain is lost, we have a list of 'stack frames' on the heap, linked top down by the state variables 'con' and 'it', so when we 're-enter' the top level generator, control is threaded down to where we last left off at every level of the tree. This is expensive compared to procedures which dispatch directly, but there's no help for it whilst we're using the machine stack as a way to hold function return addresses. [Awesome! It actually works!! Lol!] -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language