Use async when two defs or named scripts do not depend on each other and you want them to overlap. The runtime starts each call immediately and gives you a handle. The handle becomes a string on the first read that needs the value, or at the end of the current step list.
This page is a recipe. The value model lives in Async Handles. The syntax table lives in Language, async.
export def main.'…'() cannot be async — move the body into a named script.Hold each handle in its original binding. Any read that needs the string resolves the handle, so avoid these until you want the value:
log "${lint_h}";${lint_h} before the call;if or match subject;const copy = lint_h, since a bare copy is rewritten to "${lint_h}" and resolves too.An early read makes the def wait at that point, which removes the overlap.
def lint() {
return check_lint()
}
def unit_tests() {
return check_tests()
}
export def main() {
const lint_h = async lint()
const test_h = async unit_tests()
log "lint: ${lint_h}"
log "tests: ${test_h}"
}
A bare async lint() with no capture still starts the work. The implicit join at the end of the step list waits for it.
catch and recover attach only to the statement form. A captured const h = async foo() cannot carry those blocks. Wrap the target in a def if you need both a handle and a retry loop.
export def main() {
async deploy() recover (err) {
logerr "repair; see ${err}"
auto_repair()
}
}
recover retries inside that one branch. catch runs once; a successful catch counts the branch as joined-ok. A catch return becomes the parent def’s return when the join adopts it.
for loopfor line in h does not resolve a handle. The loop iterates the token as one line, so you get one pass over __JAIPH_HANDLE__… instead of one pass per result line. Resolve first:
const text = "${h}"
for line in text {
log line
}
async calls and reads the handles only at the end. The live tree prefixes each branch with a subscript (₁, ₂).log lines and the run still exits 0 after both branches complete.for line in h runs once (the token is one line). After const text = "${h}", for line in text runs once per result line.examples/async.jh is a two-backend sample of the same pattern.
await.async — surface syntax.