Coroutines
The :std/coroutine
library provides support for continuation-based and thread-based coroutines.
Continuation-based coroutines are created with coroutine
, while thread-based coroutines are
created with cothread
. Both types of coroutine are resumed with continue
and yield results
with yield
.
Continuation-based coroutines are more lightweight, but by virtue of implementation they cannot
use yield
inside finalizer blocks.
Thread-based coroutines are more heavyweight, but don't suffer from this problem as they have
a delimited dynamic scope.
usage
(import :std/coroutine)
Interface
coroutine
(coroutine proc arg ...)
proc := procedure
-> <coroutine>
Creates a new coroutine that evaluates proc with arguments (proc arg ...)
.
The coroutine is initially a suspended continuation, and can be resumed
with continue
.
coroutine?
(coroutine? obj)
-> boolean
Returns true if the object is a coroutine.
cothread
(cothread proc arg ...)
proc := procedure
-> <cothread>
Creates a new cothread that evaluates proc with arguments (proc arg ...)
.
The thread is initially suspended, and can be resumed with continue
.
cothread?
(cothread? obj)
-> boolean
Returns true if the object is a cothread.
continue
(continue co arg ...)
co := coroutine or cothread
-> any
Resumes the coroutine or cothread, with the arguments becoming the values of the last yield. If the continuable was in initial suspended state, then it is resumed and the arguments are ignored.
yield
(yield arg ...)
Continues execution of the main routine or thread, with the arguments becoming the values of the last continue.
cothread-stop!
(cothread-stop! co)
co := cothread
Stops the execution of a cothread.
Example
Here is a coroutine that iterates from 1 to n, yielding them as values and ending the generation
with the symbol end
.
(def (1-to-n n)
(let lp ((i 1))
(when (<= i n)
(yield i)
(lp (1+ i))))
'end)
;; iterate through the values yielded by the coroutine
(let (cort (coroutine 1-to-n 10))
(let lp ()
(let (next (continue cort))
(unless (eq? next 'end)
(displayln next)
(lp)))))
;; displays:
1
2
3
4
5
6
7
8
9
10