(because like. advancing a coroutine through a foreign call is a very useful thing to be able to do. that is how pants works with rust and python)
Discussion
oh goodness me these threads have a lot of stuff attached. sitting my ass down and learning
coroutine threads seem to have such wildly divergent semantics that it still really shocks me that they're interchangeable. like (thread-receive) would seem to either yield execution of the current coroutine, or to block an OS thread (risking e.g. deadlock). and then there's this:
Unless otherwise noted, all constant-time procedures and operations provided by Racket are thread-safe in the sense that they are atomic
it's technically true that operations which are atomic for a single-threaded coroutine are also atomic in the sense of the processor memory model, but i think that comparison obscures more than it enlightens. is there a way to do a multithreaded coroutine executor?
this docs paragraph from the C API seems outdated now? https://docs.racket-lang.org/inside/cs-overview.html#(part._.Racket_.C.S_and_.Threads)
Racket implements threads for Racket programs without aid from the operating system or Chez Scheme’s threads, so that Racket threads are cooperative from the perspective of C code. Stand-alone Racket uses a few private OS-implemented threads for background tasks, but these OS-implemented threads are never exposed by the Racket API.
i'm also really miffed by the "racket's road to parallelism" section failing to describe when and why racket got the coroutine thread abstraction and what considerations motivated its design