prometeu-studio/docs/agendas/Dynamic Semantics - Effect Surfaces Agenda.md
2026-03-24 13:42:17 +00:00

96 lines
3.7 KiB
Markdown

# Dynamic Semantics - Effect Surfaces Agenda
Status: Working agenda (pre-spec)
Purpose: close the runtime behavior of PBS effect and control surfaces before drafting the dynamic semantics spec
## 1. Context
PBS v1 already commits to several user-visible effect surfaces:
- `optional`,
- `result<E>`,
- `apply`,
- `bind`,
- `switch`,
- `if`,
- `else`,
- `handle`,
- `!` result propagation.
Static semantics explains where these forms are legal.
What is still missing is the runtime contract: evaluation timing, payload extraction behavior, propagation order, and interaction with traps and allocation.
## 2. Decisions to Produce
This agenda must end with decisions for:
1. The runtime value model of `optional` and `result<E>`.
2. The evaluation and propagation semantics of `apply`, `bind`, `else`, `!`, and `handle`.
3. The runtime branch-selection model for `if` and `switch`.
4. The exact boundary between explicit status values and true runtime traps.
## 3. Core Questions
### Q1. `optional`
- Is `some(expr)` evaluated eagerly before container construction?
- Does `opt else fallback` evaluate `fallback` only on `none`?
- Is `optional` guaranteed trap-free at runtime except for traps produced by evaluating its subexpressions?
### Q2. `result<E>`
- Is `ok(...)` / `err(...)` purely a return-flow construct with no standalone runtime value form in v1?
- How exactly does `expr!` propagate failure through the enclosing function?
- Does `handle expr { ... }` first evaluate `expr`, then dispatch exactly one remapping arm, or are there any hidden intermediate forms?
### Q3. `apply`
- Is direct-call sugar defined entirely through canonical `apply`, including runtime order?
- When `apply` resolves to a callback, method, contract implementation, or host-backed callable, what runtime steps are shared and what remains callable-specific?
- Must `apply` preserve a single common trap model regardless of callable kind?
### Q4. `bind`
- What runtime artifact does `bind(context, fn_name)` produce: a nominal callback pair, hidden object, or other VM-level value category?
- Is the `context` expression always evaluated exactly once at bind time?
- Does `bind` itself allocate, and if yes, must that be part of the visible cost contract?
### Q5. `switch` and `if`
- Is the selector/condition evaluated exactly once before branch selection?
- Does `switch` compare enum cases and scalar literals via a single equality model, or are there construct-specific rules?
- Are non-selected arm blocks guaranteed not to evaluate at all?
### Q6. Status values vs traps
- Which user-visible failures must stay in `optional` / `result` space instead of trapping?
- Are there any operations over these surfaces that may still trap despite their explicit effect model?
### Q7. Allocation and copy visibility
- Which of these constructs may allocate, copy, or retain heap state as part of normal execution?
- Which of those costs must be reflected later by the diagnostics spec?
## 4. Expected Spec Material
After discussion, this agenda should directly feed sections of `Dynamic Semantics Specification.md` covering:
1. runtime values and carrier forms,
2. call and callback execution,
3. effect propagation and remapping,
4. conditional and branching execution,
5. trap versus status-value behavior for effect-bearing constructs.
## 5. Non-Goals
- Revisiting the static typing surface already settled in `4. Static Semantics Specification.md`.
- Designing collection APIs or general async/error subsystems.
- Reopening reserved syntax such as future `match`.
## 6. Inputs
- `3. Core Syntax Specification.md`
- `4. Static Semantics Specification.md`
- `Heap Model - Agenda.md`
- `Dynamic Semantics - Execution Model Agenda.md`