thread - pannous/warp GitHub Wiki
async threading follows the go/zig path to be invoked on the caller side.
On the callee side, functions are agnostic whether they are called in a synchronous or asynchronous way.
This way function coloring and the huge syntactic and semantic async/await overhead mess is avoided:
shared done = false
go { sleep 1s; print "second"; done = true }
print "first"
last = after done return "third"
print await last or "no third"
prints first, second, third. A task works on copies (task): only shared values (and shared arrays) are seen by
every task (decision P106), so done is declared shared; after on a variable that is not shared is an error.
cancel last stops the waiting task, and await last or "no third" then gives the fallback:
shared done = false
last = after done return "third"
cancel last
print await last or "no third"
The after keyword creates an (aspect oriented) implicit signal listener on the variable done: a task that
waits until the condition holds, then gives its value. (Write after (n == 5) return x with parentheses for now.)
Concurrent or asynchronous tasks can be paused, stopped, etc
Avoiding Function coloring: https://news.ycombinator.com/item?id=28657358
Prior art: Bend/HVM
The parallel let comes from Bend 2 (HigherOrderCO, Victor Taelin):
a b = sum(d - 1) sum(d - 1) # Bend
The parallel let is written without let: names on the left, as many calls on the right. let a b = … is not it:
let before two names defines a function a of b, so it fails with "let needs a value".
runs both calls at once: the first as a task, the second on the current thread, then waits for the first. As in Bend's runtime BendRT, a fork met while all cores are busy runs as a plain call, so a recursive split forks only its top levels. Bend's earlier runtime HVM (interaction nets) is not used: Bend itself left it. Ideas taken, no code copied.