Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Several things at once

ASYNC

Put ASYNC in front of a call and it starts on a thread of its own. You get a future back straight away and carry on. RESOLVE waits for a future and gives you its answer.

FUNCTION slow_square(n)
    FOR i = 1 ... 2000
        // pretend this is hard work
    END FOR
    RETURN n * n
END FUNCTION

first = ASYNC slow_square(3)
second = ASYNC slow_square(4)
PRINT "both are working..."
PRINT RESOLVE(first), RESOLVE(second)
PRINT RESOLVE(first, second)      // several at once come back as a list
both are working...
9 16
[9, 16]

Any function can be started this way, and any line can wait for one.

ATOMIC

Threads share the program’s variables. When several are changing the same one, mark it ATOMIC and each change happens as a single step, so none get lost.

ATOMIC counted = 0

FUNCTION count(times)
    FOR i = 1 ... times
        counted = counted + 1
    END FOR
END FUNCTION

RESOLVE(ASYNC count(500), ASYNC count(500), ASYNC count(500))
PRINT counted
1500

From JavaScript: ASYNC f() gives you something like a promise and RESOLVE is await — but it works anywhere, in any function.

From Python: Like submitting to a thread pool and calling .result(), with nothing to set up.

From Lua: Not coroutines: nothing has to yield. I share the time out myself.

From BASIC: No timers and flags to juggle. Start it, carry on, and ask for the answer when you want it.

Crash-tan’s Tip: A program I’m running inside can also start a call later, or again and again — that’s how timers are made, with modifiers: ASYNC blink() !! every(500). This tutorial doesn’t offer those, but a game engine will.