35. Coroutines and additional generator support
The COROUTINES module exposes coroutine infrastructure, as well as additional yielding facilities.
The following example illustrates iterating over the elements of a tree. each_async_generator implements straight up iterator, where ‘yield_from’ helper is used to continue iterating over leafs. [coroutine] annotation converts function into coroutine. If need be, return type of the function can specify coroutine yield type:
require daslib/coroutines
struct Tree
data : int
left, right : Tree?
// yield from example
def each_async_generator(tree : Tree?)
return <- generator<int>() <|
if tree.left != null
yeild_from <| each_async_generator(tree.left)
yield tree.data
if tree.right != null
yeild_from <| each_async_generator(tree.right)
return false
// coroutine as function
[coroutine]
def each_async(tree : Tree?) : int
if tree.left != null
co_await <| each_async(tree.left)
yield tree.data
if tree.right != null
co_await <| each_async(tree.right)
All functions and symbols are in “coroutines” module, use require to get access to it.
require daslib/coroutines
35.1. Type aliases
- Coroutine = iterator<bool>
A coroutine is a generator that yields bool to indicate if it is still running.
- Coroutines = array<iterator<bool>>
An array of coroutines.
35.2. Function annotations
- coroutine
This macro converts coroutine function into generator, adds return false. Daslang impelmentation of coroutine is generator based. Function is converted into a state machine, which can be resumed and suspended. The function is converted into a generator. Generator yields bool if its a void coroutine, and yields the return type otherwise. If return type is specified coroutine can serve as an advanced form of a generator.
35.3. Call macros
- co_continue
This macro converts co_continue to yield true. The idea is that coroutine without specified type is underneath a coroutine which yields bool. That way co_continue() does not distract from the fact that it is a generator<bool>.
- co_await
This macro converts co_await(sub_coroutine) into:
for t in subroutine
yield t
The idea is that coroutine or generator can wait for a sub-coroutine to finish.
- yeild_from
This macro converts yield_from(THAT) expression into:
for t in THAT
yield t
The idea is that coroutine or generator can continuesly yield from another sub-coroutine or generator.
35.4. Top level coroutine evaluation
- cr_run(a: Coroutine)
This function runs coroutine until it is finished.
- Arguments:
a : Coroutine
- cr_run_all(a: Coroutines)
This function runs all coroutines until they are finished.
- Arguments:
a : Coroutines