This was the main driving force behind the development of Polyphony. I've been exploring all the different ways of expressing concurrent operations: callbacks, promises, async/await. Each of these solutions has its drawbacks: callbacks make you split your app logic across different functions; promises are a somewhat better API but do not solve the split logic problem; async/await potentially leads to two types of functions (the "what color is your function" problem). All three kind of break Ruby's exception handling model.
In contrast, Polyphony relies on Ruby fibers, which provide a base for implementing cooperative concurrency, where each fiber does its work, yielding execution whenever it performs a blocking operation, such as reading from a socket, or waiting for a timeout. In addition, fibers are arranged into a tree where each fiber is considered the child of the fiber from which it was spawned, and is guaranteed to stop executing before its immediate parent stops executing. Any uncaught exception raised by a fiber will be propagated up the fiber tree. This implements a pattern known as Structured Concurrency [1]. Fibers can communicate by sending each other messages, in a similar fashion to Erlang/Elixir processes.
There's no direct equivalent in Polyphony to the program you included, which seems to implement two generators running asynchronously. But the following does something similar.
def number_generator
n = 0
loop do
client = receive
client << (n += 1)
end
end
task1 = spin { number_generator }
task2 = spin { number_generator }
10.times do
task1 << Fiber.current
puts "next number from task1: #{receive}"
task2 << Fiber.current
puts "next number from task2: #{receive}"
end
So in the above program, two fibers are spun, each running the same number generator, which repeatedly waits for a message which is actually the fiber of the "client", and sends the next number to the client. In Python there's the Trio library [2], which implements structured concurrency, and which was actually one of the main inspirations for developing Polyphony.
[1] https://en.wikipedia.org/wiki/Structured_concurrency
[2] https://github.com/python-trio/trio