Declaration
Coroutines are declared using the pecan.Co.co
expression macro. The macro takes between 1 and 3 arguments:
- the body of the coroutine,
- (optional) the input type, and
- (optional) the output type.
The 1st argument can either be a Haxe expression (usually a block expression), or a function. The latter case allows declaring arguments (see invoking) and explicitly annotating return types (see states).
Within the code block, these variables and functions are implicitly available:
self
- refers to the current instance ofpecan.ICo<...>
.suspend()
andterminate()
- see suspending.accept()
andyield(...)
- see I/O.label(...)
- see labels.
Example: coroutine declarations and arguments
// takes two arguments whose types are inferred, return type is also inferred
pecan.Co.co((a, b) -> { ... });
// takes two arguments (second is optional), returns `String`
pecan.Co.co(function(a, ?b:Int):String { ... });
Both the 2nd and 3rd arguments may be null
or (_ : T)
where T
is a type.
Example: combinations of I/O types
// no input or output:
pecan.Co.co({ ... });
// input but no output:
pecan.Co.co({ ... }, (_ : Int));
// output but no input:
pecan.Co.co({ ... }, null, (_ : Int));
// both input and output
pecan.Co.co({ ... }, (_ : Int), (_ : Int));
Syntax helpers
pecan
provides some syntax shorthands. To use it within a class, implement the interface pecan.Syntax
.
Example: using the syntax helper
class Example implements pecan.Syntax { ... }
The syntax shorthands are:
Syntax | Equivalent to |
---|---|
!{ ... } |
pecan.Co.co({ ... }).run() |
!function():T { ... } |
pecan.Co.co(function():T { ... }).run() |
@:pecan.co(io...) function x(args...):T { ... } |
function x(args...) return pecan.Co.co(function(args...) { ... }, io...).run(args...); |
Example: !
prefix for immediately invoked coroutines
var co = !{
trace("foo");
suspend();
trace("bar");
};
co.wakeup();
Example: !
prefix for immediately invoked coroutines with explicit return type
var co = !function():String {
suspend();
return "hello";
};
co.wakeup();
Note that the return type is inferred, so this example would work without the function
as well. However, there may be some cases where an explicit type hint is required for correct compilation.
Example: @:pecan.co
methods
The syntax also allows declaring class methods as coroutines, using the :pecan.co
metadata. The metadata may optionally take up to two arguments, representing the input and output types (same as the 2nd and 3rd arguments of pecan.Co.co
):
class Example implements pecan.Syntax {
@:pecan.co function noInputNoOutput() {
suspend();
// ...
}
@:pecan.co((_ : Int)) function acceptsInts() { ... }
@:pecan.co(null, (_ : String)) function yieldsStrings() { ... }
}
A call to a method thusly annotated is equivalent to a call to run(...)
, i.e. it will return a coroutine instance.