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.

This will require notifying futures/promises. Relevant reading:

It will also require an ambient thread pool.

 

Implementation Notes

This proposal has been coded up and the result is available here: https://github.com/relevance/clojure/tree/core-futures Note: the implementation of futures should be considered in "draft" phase, it will change radically before an alpha is released. 

There are 4 major steps to this implementation:

1) The expression inside the state-machine macro is transversed

2) For each node an instruction for a virtual machine is recorded

3) These instructions (in a SSA style block format) are analyzed to find temporary variables

4) The instructions are emitted as a state machine. 

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: