Skip to content

Async functions as state machines

Category: Async · Status: stub · Lessons: chapter 06, Async (planned)

One line: A compiler turns an async function into a state machine whose states are its suspension points, storing the local variables that live across each await.

How it connects

flowchart LR
  n_async_state_machine["Async functions as state machines"]
  n_coroutine["Coroutine"]
  n_async_state_machine -->|uses| n_coroutine
  classDef center stroke-width:3px
  class n_async_state_machine center
  classDef outside stroke-dasharray: 4 3
  class n_coroutine outside

In each language

Rust the compiler turns async code into an invisible state machine that a runtime drives (Book ↗)
C++ a coroutine ↗ keeps its promise, parameters, suspension point and locals in a coroutine state, allocated dynamically unless the allocation is optimized out
C# the compiler generates a state machine for each async method, implementing IAsyncStateMachine
Kotlin a suspended computation is resumed through a Continuation, which represents the rest of the work after a suspension point

Where to read more

  • In the books: Asynchronous Programming in Rust, Carl Fredrik Samson — ch. 7, 'Coroutines and async/await' → 'Introduction to stackless coroutines'
  • In the books: asyncio Recipes, Mohamed Mustapha Tahrioui — ch. 4, 'Working with Async Generators' → 'Writing a State Machine with an Async Generator'
  • In the books: Async Rust, Maxwell Flitton, Caroline Morton — ch. 9, 'Design Patterns' → 'The State Machine Pattern'
  • In the books: Erlang Programming, Francesco Cesarini, Simon Thompson — ch. 5, 'Process Design Patterns' → 'Finite State Machines'
  • Notes: async functions - state machines - rust ↗