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
coroutines::cr_run_all(a: Coroutines)

This function runs all coroutines until they are finished.

Arguments