Skip to content

Concurrency Compile Time And Unsafe

Chris Michael edited this page Sep 2, 2026 · 3 revisions

Pudu

Concurrency, Compile Time, And Unsafe

This overview records how the three execution boundaries meet. Their complete rules now live in Tasks And Scopes, Compile-Time Evaluation, Typed Macros, and References And Unsafe.

export async fn main() -> Result[Int, Str] {
  async with scope {
    let value = work().await
    Ok(value)
  }
}

Status: async functions, cold tasks, await, deterministic task-tree scopes, compile-time purity checks, typed macros, and unsafe capability checks are implemented in the checker/interpreter. Scheduling, concurrent execution, cancellation, native threads, memory layout, pointers, and FFI delivery are not implemented.

Async and structured scopes

Calling async fn constructs a cold Task[T, E]. Inside a scope, constructing the task registers it as a child; evaluation starts when it is awaited or when the scope joins it on exit. .await is legal only in an async function or async block and yields the task success value; the failure channel belongs to the enclosing async computation. The reserved spawn keyword is not implemented.

async with scope { ... } owns its registered children. The interpreter joins unawaited children sequentially in creation order when the scope exits. A child failure propagates through the interpreter's ordinary task result. There is no cancellation state or API, scheduler, parallel execution, or detached task facility. An async main is the program entry point for task-tree evaluation.

The interpreter implements this deterministic sequential model. Native scheduling, actual concurrency, cancellation, and Send/Sync enforcement remain future runtime/backend work.

Compile-time execution

comptime fn square(value: Int) -> Int { value * value }
const FOUR = square(2)

Compile-time work uses the ordinary evaluator with IO, environment, time, randomness, unsafe operations, and tasks denied. The static checker restricts direct calls to named comptime functions and approved built-ins. Function values do not carry comptime metadata, so higher-order or aliased calls are not checked transitively. Runtime effect denial still prevents an indirect call from reaching the outside world while a constant is folded. Loop-step and call-depth limits bound evaluation; there is no memory budget.

Typed macros

macro twice(value: expr) = {
  let held = value
  held + held
}

Macro parameters accept expr, ident, or block. Calls use twice!(expression). Expansion is hygienic and bounded. Macros cannot read files, environment, network, compiler internals, or host code. Repetition syntax is not defined.

Unsafe capabilities

unsafe(raw) {
  operationRequiringRawCapability()
}

Capability names are raw, foreign, unchecked, and null. For a direct call to a named unsafe function, a named region grants only those capabilities and a bare unsafe region grants the blanket set. Safe type checks remain active inside the region, and an unused explicit grant is reported.

Function types do not retain unsafe or capability metadata. Calling an unsafe function through an alias or higher-order value is therefore not rejected at present. Capability-bearing function types and transitive higher-order enforcement are not implemented.

This is a partial checked boundary, not a complete safety or FFI guarantee. Stable foreign declaration syntax, raw-pointer types, ABI layouts, native lowering, higher-order capability tracking, and native safety conformance are not implemented.

Related

Clone this wiki locally