5.8 KiB
Dynamic Semantics - Execution Model Decision
Status: Accepted (Implemented) Cycle: Initial execution-model closure pass
1. Context
PBS needs a closed execution-model baseline before effect surfaces and memory/lifetime semantics can be specified normatively.
The key open questions were:
- whether execution is single-threaded per program instance,
- which runtime effects are observable to user code,
- what the default evaluation order is,
- which constructs guarantee single evaluation,
- how abrupt completion behaves,
- how
result<Error>differs fromtrap, - and how host calls interact with
FRAME_SYNCwithout perturbing user-visible sequencing.
2. Decision
PBS v1 adopts the following execution-model baseline:
- Execution is single-threaded per program instance.
- User-visible execution is deterministic and does not expose concurrent interleaving.
- The default evaluation rule is strict left-to-right unless a construct explicitly states otherwise.
- Call evaluation proceeds by forming the call target first, then evaluating arguments left-to-right, then invoking the target.
- Abrupt completion terminates the current construct immediately and prevents later sibling evaluation.
- Recoverable, expected failures belong to
result<Error>, not totrap. trapis reserved for non-recoverable runtime failures outside ordinary userland error flow.- Any trap aborts the current PBS program execution rather than returning control to ordinary userland flow.
FRAME_SYNCis the only normative safepoint in PBS v1.FRAME_SYNCremains the execution boundary for userland progress; host-side work during that boundary must not reorder PBS-observable semantics.
3. Invariants
- PBS v1 does not expose a user-visible concurrent execution model.
- User-visible sequencing is defined by evaluation order, branch selection, abrupt completion, result propagation, trap propagation, and host-call boundaries.
- Traps are not recoverable in userland and do not resume PBS execution.
- VM-internal frame layout, temporary storage, and lowering steps are not observable unless they change the semantic effects above.
- Unless a construct states otherwise, subexpressions are evaluated once and in left-to-right order.
return,break,continue, result propagation via!, andtrapabort further evaluation in the current construct.- Host calls must not introduce user-visible reordering of already-defined PBS evaluation order.
- No normative safepoint exists in v1 other than
FRAME_SYNC.
4. Call Evaluation Rule
The runtime call rule for v1 is:
- Form the call target.
- Evaluate any receiver that participates in target formation.
- Evaluate arguments in source order from left to right.
- Invoke the resolved target.
- Produce one of:
- normal return,
- explicit
result<Error>propagation, - or
trap.
This rule applies to canonical apply and to ordinary call sugar that desugars to apply.
5. Error Boundary
result<Error> and trap are distinct runtime categories.
5.1 result<Error>
result<Error> is the required mechanism for failures that are:
- expected by the API contract,
- recoverable in ordinary userland control flow,
- modelable through an explicit PBS error type.
Such failures may be:
- processed with
handle, - propagated with
!, - and discussed as part of ordinary function contract design.
5.2 trap
trap is reserved for failures that are:
- outside the ordinary userland contract,
- not suitably representable as the declared
result<Error>surface, - caused by runtime or host invariant failure,
- or severe enough that ordinary userland recovery is not part of the v1 language model.
PBS v1 does not define try/catch for traps.
Traps are not part of ordinary recoverable control flow.
Once a trap is raised, PBS userland execution aborts and control transfers to runtime or firmware crash handling outside the ordinary language model.
6. Consequences
- User-authored code does not explicitly throw traps as part of ordinary PBS semantics.
- API surfaces must not use trap as a substitute for a modelable
result<Error>failure. - Host-backed operations must expose predictable operational failures through
result<Error>when those failures are part of the callable contract. - Residual host or runtime failures that cannot be represented by the declared PBS contract may still trap.
- The language-level consequence of trap is program abort rather than catchable failure handling.
- In v1, no safepoint inventory is normative beyond
FRAME_SYNC.
7. Explicit Non-Decisions
This decision does not yet close:
- the exact list of constructs with explicit single-evaluation wording as finally integrated into the dynamic-semantics spec,
- the final wording split between dynamic semantics and runtime-initialization for trap/crash handoff.
Those points must be integrated by the remaining dynamic-semantics and memory/lifetime decisions.
8. Spec Impact
This decision should feed at least:
docs/pbs/specs/9. Dynamic Semantics Specification.mddocs/pbs/specs/10. Memory and Lifetime Specification.mddocs/general/specs/16. Runtime Execution and Initialization Specification.md
It should also constrain future work in:
docs/pbs/specs/12. Diagnostics Specification.mddocs/general/specs/13. Conformance Test Specification.md
9. Validation Notes
The intended rule is:
- expected domain failure:
result<Error> - remappable, processable, or propagatable failure:
result<Error> - runtime invariant breakage or non-contract catastrophic failure:
trap
In practical terms, a host-backed API must not rely on trap for ordinary operational failures if those failures can be declared and modeled explicitly in PBS. The only normative safepoint in v1 is FRAME_SYNC, and any trap aborts PBS userland execution rather than returning through an in-language recovery path.