9.4. Coroutines and additional generator support
The COROUTINES module provides coroutine infrastructure including the
[coroutine] function annotation, yield_from for delegating to
sub-coroutines, and co_await for composing asynchronous generators.
Coroutines produce values lazily via yield and can be iterated with
for.
See Iterators and Generators for a hands-on tutorial.
All functions and symbols are in “coroutines” module, use require to get access to it.
require daslib/coroutines
Example:
require daslib/coroutines
[coroutine]
def fibonacci() : int {
var a = 0
var b = 1
while (true) {
yield a
let next = a + b
a = b
b = next
}
}
[export]
def main() {
var count = 0
for (n in fibonacci()) {
print("{n} ")
count ++
if (count >= 10) {
break
}
}
print("\n")
}
// output:
// 0 1 1 2 3 5 8 13 21 34
9.4.1. Type aliases
- coroutines::Coroutine = iterator<bool>
A coroutine is a generator that yields bool to indicate if it is still running.
- coroutines::Coroutines = array<iterator<bool>>
An array of coroutines.
9.4.2. Function annotations
- coroutines::coroutine
This macro converts coroutine function into generator, adds return false. Daslang implementation 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.
9.4.3. Call macros
- coroutines::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>.
- coroutines::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.
- coroutines::yeild_from
This macro converts yield_from(THAT) expression into:
for t in THAT
yield t
The idea is that coroutine or generator can continuously yield from another sub-coroutine or generator.
9.4.4. Top level coroutine evaluation
- coroutines::cr_run(a: Coroutine)
This function runs coroutine until it is finished.
- Arguments
a : Coroutine
- coroutines::cr_run_all(a: Coroutines)
This function runs all coroutines until they are finished.
- Arguments
a : Coroutines