(sigil coroutines)
(sigil coroutines) - Bidirectional Coroutines
Coroutines that can both send values to and receive values from the caller. Unlike generators (which only yield), coroutines enable true bidirectional communication through send and receive.
Basic Usage
(import (sigil coroutines))
;; A coroutine that doubles input values
(define doubler
(coroutine
(let loop ((x (receive)))
(loop (send (* x 2))))))
(coroutine-send doubler 5) ; => 10
(coroutine-send doubler 21) ; => 42Control Flow Inversion
Coroutines are useful for inverting control flow. For example, in game loops where C code controls the main loop but Scheme code needs to appear as if it owns execution:
(define game-loop
(coroutine
(let loop ((state (receive)))
(let ((new-state (update-game state)))
(loop (send new-state))))))Exports
coroutine?procedureCheck if obj is a coroutine.
(coroutine? (coroutine (send 1))) ; => #t
(coroutine? '(1 2 3)) ; => #fcoroutine-done?procedureCheck if a coroutine has finished execution.
A coroutine is done when its body returns (without calling send).
(define c (coroutine (send 1)))
(coroutine-done? c) ; => #f
(coroutine-send c 'x) ; => 1
(coroutine-done? c) ; => #tsend-receiveprocedureSend a value and receive the next input.
This is the low-level primitive used by the send macro. Prefer using the send macro for cleaner syntax.
make-coroutineprocedureCreate a coroutine from a thunk.
The thunk should use send to yield values and receive to get values from the caller. Prefer using the coroutine macro for cleaner syntax.
(define c (make-coroutine
(lambda ()
(let loop ((x (receive)))
(loop (send (* x 2)))))))
(coroutine-send c 5) ; => 10
(coroutine-send c 10) ; => 20coroutine-sendprocedureSend a value to a coroutine and get its response.
Resumes the coroutine, providing val as the result of its pending receive call. The coroutine runs until it calls send, and that sent value becomes the return value of coroutine-send.
Returns #f if the coroutine finishes without sending a value. Raises an error if the coroutine is already done.
(define echo (coroutine
(let loop ((x (receive)))
(loop (send x)))))
(coroutine-send echo 'hello) ; => hello
(coroutine-send echo 'world) ; => worldcoroutinevariable(No description)
sendvariable(No description)
receivevariable(No description)