I've been thinking about reactive programming from the runtime layer up. The question: what's the minimum machinery you actually need to add on top of Rust's async/await to get a working reactive system?
Three things Rust already gives you for free
Pin> = a suspended computation
Think about it: a reactive effect is "a piece of code paused, waiting for its dependencies to change, then re-executing." That's exactly what a future stuck at Poll::Pending is.
scope.spawn(async move {
loop {
count.changed().await; // suspends here
println!("count = {}", count.read());
}
});
The SignalChangedFuture::poll() checks a monotonic version number. If unchanged, it subscribes a callback and returns Poll::Pending. The async executor polls other tasks. When the signal changes, the version bumps, the callback fires, the waker wakes, the executor re-polls.…