Temporal decorators

Scheduling via decorators: @every, @after, and @cron.

Summary

Apply @every(duration) to a function to run it repeatedly at a fixed interval. Apply @after(duration) to run it once after a delay. Apply @cron("expr") to run it on a cron schedule. All three forms accept a Duration literal (or a plain number treated as milliseconds). These are decorator forms - they attach to a named function declaration, not to a bare block.

Canonical

Temporal primitives are scheduling constructs that take a Duration. They also accept plain numbers, which are interpreted as milliseconds for compatibility.

every

Runs a block repeatedly at a fixed interval. In the interpreter, the body runs once (for deterministic script execution). When transpiled to JavaScript, it maps to setInterval.

every 1s {
    println("tick")
}

after

Runs a block once after a delay:

after 500ms {
    println("delayed hello")
}

timeout

Runs a block with a time limit. If the block doesn't finish in time, the else fallback runs instead:

timeout 2s {
    let result = slow_computation()
    println(result)
} else {
    println("timed out")
}

debounce

Debounces execution - if called repeatedly, only the last call within the window actually runs:

debounce 300ms {
    println("search: {query}")
}

Practical examples

-- polling with every
var health = "unknown"
every 30s {
    health = check_server()
}

-- delayed initialization
after 2s {
    connect_to_database()
}

-- request with timeout
timeout 5s {
    let data = fetch_api("/users")
    process(data)
} else {
    println("API request timed out, using cache")
    process(cached_data)
}

-- debounced input handling
var query = ""
fn on_input(text) {
    query = text
    debounce 200ms {
        search(query)
    }
}