Felix now supports first class iterators, as a special
case of generators. Here is an example:

------------------------------------
#import <flx.flxh>

gen f(init:int)(inc:int):int = {
  var counter = init;
again:>
  counter += inc;
  yield counter;
  goto again;
}

var x = f(40);
print$ x(2); endl; // 42
print$ x(2); endl; // 44 
print$ x(10); endl; // 54
print$ x(10); endl; // 64
---------------------------------
Output:
---------------------------------
[EMAIL PROTECTED]:/work/felix/svn/felix/felix/trunk$ flx --test --force xx
42
44
54
64
---------------------------------
Note the new keyword 'gen' which denotes a generator.
A generator is any function with internal state.
C bindings must also be declared generators if they
access state, for example: malloc(), random() etc are generators.
All class constructors are also generators.

Generators are replaced by variables in expressions,
and the variable is initialised (eagerly) by the generator.
This prevents duplication of the generator call, leading
to inconsistent results.

When a generator is stored in a variable, invoking
it does NOT cause the previous state to be lost.
Therefore, generators stored in variables are not
re-entrant. Note that of course you can call a generator
explicitly from itself -- you just can't call it using the 
same closure. In the above generator, the state variable

        counter

is not lost between invocations.

I know you don't need to ask what yield does. It is clear,
it returns a value just like 'return'. The difference
is when the generator is re-entered .. it jumps right
to the pointer after the yield and keeps going.

You can also see in the example that you can 'resupply'
a generator with a new argument, which is assigned to the
parameter before jumping off to the last point.

Here is another example:
-----------------------------------------
#import <flx.flxh>

gen f():int = {
  var counter = 0;
again:>
  ++counter;
  yield counter;
  yield counter+10;
  goto again;
}

var x = the f;
print$ x(); endl; // 1 
print$ x(); endl; // 11
print$ x(); endl; // 2 
print$ x(); endl; // 12
print$ x(); endl; // 3
-------------------------------------
[EMAIL PROTECTED]:/work/felix/svn/felix/felix/trunk$ flx --test --force xx
1
11
2
12
3
-----------------------------------

The 'canonical' use of generators is as STL iterators.
You can write a loop which runs from begin() to end(),
yielding each value in turn.

Such iterators are POLYADIC which C++ ones are not.
In other words, their type depends only on the value type
of the container, not the container type. Whilst C++
iterators are merely generic, Felix ones admit dynamic
binding. [Of course you can also do this in C++, otherwise
Felix wouldn't be able to do it :]

So for example you can write an 'accumulate' functions
which accepts an iterator over 'int' and it will happily
add up the contents of ANY container type.

The key point here, obviously, is, as usual the control
inversion the 'yield' statement provides.
The implementation is much the same as for procedures,
except that yield returns a user value, not a continuation.

Also note, yield is NOT transitive, which is another difference
to procedures: procedures can read/write a channel at any
depth of recursion or nesting and the whole call stack
is suspended. Yielding deep in a function call stack only
suspends the top of the stack, and the suspension
would be lost were it not stored in a variable.

Finally not that whilst you CAN copy suspensions ..
be warned they're just pointers and you're passing
by reference not value.


-- 
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

Reply via email to