How to model a state machine using generics? [dynamic dispatch?]

For very small state machines like this, my default approach would be to simply make everything concrete as others said--not even abstracting over events:

struct Off {
  func start() -> Listening { Listening() }
}

struct Listening {
  func stop() -> Off { Off() }
  func receive(connection id: Int) -> Receive {
    Receive(id: id)
  }
}

struct Receive {
  let id: Int
  func stop() -> Off { Off() }
}

This has the virtue that illegal transitions simply cannot be represented in the program. Sure, you can imagine making this generic, but what does that get you? Runtime errors instead of not being able to write those bugs at all.

6 Likes