prometeu-studio/docs/compiler/pbs/decisions/Dynamic Semantics - Execution Model Decision.md
2026-03-24 13:42:37 +00:00

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 from trap,
  • and how host calls interact with FRAME_SYNC without perturbing user-visible sequencing.

2. Decision

PBS v1 adopts the following execution-model baseline:

  1. Execution is single-threaded per program instance.
  2. User-visible execution is deterministic and does not expose concurrent interleaving.
  3. The default evaluation rule is strict left-to-right unless a construct explicitly states otherwise.
  4. Call evaluation proceeds by forming the call target first, then evaluating arguments left-to-right, then invoking the target.
  5. Abrupt completion terminates the current construct immediately and prevents later sibling evaluation.
  6. Recoverable, expected failures belong to result<Error>, not to trap.
  7. trap is reserved for non-recoverable runtime failures outside ordinary userland error flow.
  8. Any trap aborts the current PBS program execution rather than returning control to ordinary userland flow.
  9. FRAME_SYNC is the only normative safepoint in PBS v1.
  10. FRAME_SYNC remains 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 !, and trap abort 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:

  1. Form the call target.
  2. Evaluate any receiver that participates in target formation.
  3. Evaluate arguments in source order from left to right.
  4. Invoke the resolved target.
  5. 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.md
  • docs/pbs/specs/10. Memory and Lifetime Specification.md
  • docs/general/specs/16. Runtime Execution and Initialization Specification.md

It should also constrain future work in:

  • docs/pbs/specs/12. Diagnostics Specification.md
  • docs/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.