50. 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
50.1. Type aliases
- Coroutine = iterator<bool>
Coroutine which does not yield and value.
- Coroutines = array<iterator<bool>>
Collection of coroutines, which do not yield any value.
50.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.
50.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.