Effects as Async
Tutorial Video
Text description (accessibility)
This video demonstrates the "Effects as Async" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. Asynchronous I/O is the most widely deployed algebraic effect in mainstream programming. Key difference from OCaml: 1. **State machine vs. continuation**: Rust's `async/await` compiles to a state machine; OCaml's effect
Tutorial
The Problem
Asynchronous I/O is the most widely deployed algebraic effect in mainstream programming. Rust's async/await transforms async functions into state machines that yield control at each await point — the runtime (Tokio, async-std) is the "handler" that resumes computations when I/O completes. This example explores the conceptual connection between algebraic effects and async, showing how Future and Poll are the concrete Rust implementation of the "suspend and resume" effect model.
🎯 Learning Outcomes
async/await as syntactic sugar over the Future trait and algebraic effectsPoll::Pending and Poll::Ready correspond to effect suspension and resumptionCode Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
async/await compiles to a state machine; OCaml's effect-based async uses captured continuations — different implementations of the same semantics.await in typical use; OCaml's continuation capture allocates on the heap.Future is single-shot.eio is newer but gaining adoption.OCaml Approach
OCaml's eio library (built on OCaml 5 effects) implements async I/O via effects:
effect Await : 'a Promise.t -> 'a
let with_scheduler program =
match_with program () { effc = fun (type a) e ->
match e with
| Await p -> Some (fun k ->
Promise.on_resolve p (fun v -> continue k v))
| _ -> None }
The Await effect is intercepted by the scheduler, which registers the continuation and resumes it when the promise resolves.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Effect Async
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
join_all<F: Future>(futures: Vec<F>) -> Vec<F::Output> that concurrently awaits all futures.with_timeout(duration, future) that returns Err(Timeout) if the future takes too long.