>>108439807
>My runtime requires a single controlling loop rather than multiple small loops and locks.
Using a loop to create a multiprocess-wide context which you use as the basis of a scheduler is not really asynchronous processing. Have you considered what occurs when you get two return calls simultaneously?
Think about the implementation, consider this:
(define (sync a b c)
(cond ((= a 1) (action_a b))
((= b 2) (action_b c))
((= c 1) (action_c a)))
(sync (eval-next-a) (eval-next-b) (eval-next-c)))[\code]
This places an order on the evaluation of the processes that is, intrinsically, blocking. Imagine if 'a' constantly returned a 1, would 'b' or 'c' ever get a chance to have their actions called?
You could argue that that is simply a detriment of the example, and that a proper implementation would be completely non-blocking. But that misses the obvious issues that form the entire field of asynchronous programming.
What if 'b' depends on the state of 'a', but that state is updated before 'b' is evaluated? (temporal issues)
What if the value of 'a' changes as a result of the evaluation of 'c'? (incorrect assurances of environment sanity within an iteration)
Now imagine that these processes do everything from outputting to a display, or reading from a network socket, or performing an FFT, or sending an email and so on. When that cond expression grows larger and larger, those issues become harder and harder to control.
I'm sorry but I have to say it, don't be naive, locks and "small loops" are the only way to do actual asynchronous programming. What you have described is to gain control of purely continuous systems by discretising them into distinct steps. This is fundamentally the point of continuous engineering in general. And is a classic approach, but naive and well worn.