Problem

Futures and promises block the derefing thread. Once that is somewhat mitigated by notifying promises, we then get callback hell and inversion of control. The same issues exist in Javascript. These issues were addressed by F#, and later C# async/await, the latter of which has been copied by Scala.

Proposal

Copy C# async/await. (async ...) establishes a block, within which (await a-future-or-promise) will relinquish control, wiring up a state machine representing the rest of the block to the notification of the future/promise. The async block itself returns a promise.

5) The state machine is wrapped by functions that pack and unpack tasks

The output of the state machine macro is a function that takes an old state and produces a new state. Thus these state machines are immutable, and side affect free (assuming the code in them is also side-effect free).

Work to be done:

Think about try/catch/finally, doesn't work at the moment

Don't overload the deref value, instead we will use await to deref listenable futures

core-futures is very cool as is. It doesn't seem like try/catch/finally should be too hard to add, but I do thing it would break the ability to do state transitions via recur.

the straightforward approach would be to add a stack to the state map, and a try/catch would push a \[ExceptionType state\] pair on the stack, run the code, then pop it off. the fn created by `emit-state-machine` would have a try/catch around the body (which would break recur) that would catch Throwable, then walk the exception stack looking for a state to transition in to for that exception's type