yasync - Yet another async/await for Nim
WARNING: Doesn't work because of nim-lang/Nim#19818, but can be tested with this hacky patch to Nim.
- Semantics is very close to that of Nim's std
async,awaitandFuture[T]. -
awaitoperation doesn't cause any heap allocations (except calling manually-async functions, async closures, and (mutually) recursive calls). -
callSoonis not used and async code is guaranteed to run atomically betweenawaits across call boundaries (TODO: maybe add an example) - Function return type is written as
T, thenasynctransforms it toFuture[T]implicitly. - Provides optional compatibility layer for interop with existing
asyncdispatch(and TODO: chronos) code. Example. The library itself is completely dispatcher agnostic, and doesn't depend on neitherasyncdispatch, nor chronos.
This library introduces async, await and Future[T] similar in semantics to Nim's native ones, but implements an optimization to avoid heap allocations. Consider the following sample:
proc sleep(ms: int): Future[void] = ... # Let's assume this function doesn't allocate
proc foo(a: int): int {.async.} =
await sleep(a)
var b = a + 1
return b
proc bar() {.async.} =
let a = await foo(5)
let b = await foo(6)
echo a + b
waitFor bar()If we pretend that sleep doesn't allocate, the whole waitFor operation above will not do a single allocation (TODO: Currently waitFor allocates, but trivial to fix :) ). The optimization happens in async functions on await calls.
TODO: Describe how it works in details
TODO:
- Recursive calls
- Generics
- Cancellation
- Nice stack traces