From b865e2386ed11542ba5d273d93522d8ad44d2b5c Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 3 Mar 2026 09:47:29 +0000 Subject: [PATCH] sorted agendas e discussions generated. --- ...amic Semantics - Effect Surfaces Agenda.md | 95 ----- ...amic Semantics - Execution Model Agenda.md | 86 ----- docs/pbs/agendas/Heap Model - Agenda.md | 89 ----- .../agendas/Memory and Lifetime - Agenda.md | 94 ----- ...Allocation and Cost Visibility Decision.md | 154 ++++++++ ...c Semantics - Branch Selection Decision.md | 128 +++++++ ...ic Semantics - Effect Surfaces Decision.md | 355 ++++++++++++++++++ ...ic Semantics - Execution Model Decision.md | 131 +++++++ .../decisions/GC and Reachability Decision.md | 130 +++++++ .../Host Memory Boundary Decision.md | 115 ++++++ ...me Control and Future Profiles Decision.md | 121 ++++++ ...ue Representation and Identity Decision.md | 190 ++++++++++ 12 files changed, 1324 insertions(+), 364 deletions(-) delete mode 100644 docs/pbs/agendas/Dynamic Semantics - Effect Surfaces Agenda.md delete mode 100644 docs/pbs/agendas/Dynamic Semantics - Execution Model Agenda.md delete mode 100644 docs/pbs/agendas/Heap Model - Agenda.md delete mode 100644 docs/pbs/agendas/Memory and Lifetime - Agenda.md create mode 100644 docs/pbs/decisions/Allocation and Cost Visibility Decision.md create mode 100644 docs/pbs/decisions/Dynamic Semantics - Branch Selection Decision.md create mode 100644 docs/pbs/decisions/Dynamic Semantics - Effect Surfaces Decision.md create mode 100644 docs/pbs/decisions/Dynamic Semantics - Execution Model Decision.md create mode 100644 docs/pbs/decisions/GC and Reachability Decision.md create mode 100644 docs/pbs/decisions/Host Memory Boundary Decision.md create mode 100644 docs/pbs/decisions/Lifetime Control and Future Profiles Decision.md create mode 100644 docs/pbs/decisions/Value Representation and Identity Decision.md diff --git a/docs/pbs/agendas/Dynamic Semantics - Effect Surfaces Agenda.md b/docs/pbs/agendas/Dynamic Semantics - Effect Surfaces Agenda.md deleted file mode 100644 index c797acd5..00000000 --- a/docs/pbs/agendas/Dynamic Semantics - Effect Surfaces Agenda.md +++ /dev/null @@ -1,95 +0,0 @@ -# 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`, -- `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`. -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` - -- 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` diff --git a/docs/pbs/agendas/Dynamic Semantics - Execution Model Agenda.md b/docs/pbs/agendas/Dynamic Semantics - Execution Model Agenda.md deleted file mode 100644 index 87e1ed83..00000000 --- a/docs/pbs/agendas/Dynamic Semantics - Execution Model Agenda.md +++ /dev/null @@ -1,86 +0,0 @@ -# Dynamic Semantics - Execution Model Agenda - -Status: Working agenda (pre-spec) -Purpose: close the observable execution model for PBS before drafting the dynamic semantics spec - -## 1. Context - -Static semantics already fixes a large part of the source model, but several runtime-visible questions remain open: - -- exact evaluation order, -- what counts as a trap versus an ordinary control-flow outcome, -- how `FRAME_SYNC` and deterministic safepoints constrain execution, -- what host calls are allowed to observe or perturb execution order. - -These decisions should be closed before effect surfaces and memory/lifetime rules are written as normative dynamic semantics. - -## 2. Decisions to Produce - -This agenda must end with decisions for: - -1. The observable sequencing model for expressions, statements, and blocks. -2. The normative evaluation order for arguments, receivers, selectors, and chained `apply`. -3. The abrupt-completion model: `return`, `break`, `continue`, result propagation, and traps. -4. The interaction between host calls, safepoints, and deterministic execution. - -## 3. Core Questions - -### Q1. Global execution model - -- Is PBS execution defined as single-threaded per program instance in v1? -- Which execution steps are observable to user code, and which remain VM-internal? - -### Q2. Expression evaluation order - -- Is expression evaluation strictly left-to-right unless a construct says otherwise? -- For `f(a, b)` / `f apply (a, b)`, what is the order of evaluating callee, receiver, and argument expressions? -- For `f1 apply f2 apply x`, what is the runtime order implied by the right-associative parse? - -### Q3. Single-evaluation guarantees - -- Which constructs normatively evaluate subexpressions exactly once? -- Does that guarantee apply to `switch` selectors, `if` conditions, `opt else fallback`, `handle expr`, and `bind(context, fn_name)` context expressions? - -### Q4. Blocks and control transfer - -- How are statement sequencing and tail-expression evaluation defined inside blocks? -- At what point does `return`, `break`, or `continue` abort further evaluation in the current construct? - -### Q5. Trap model - -- Which runtime failures are traps rather than status values or compile-time rejection? -- Must trap categories be stable and named in the dynamic semantics spec? -- Are traps deterministic for the same program input and runtime capability set? - -### Q6. Host interaction - -- Can host calls introduce extra traps beyond ordinary PBS runtime failures? -- Where are safepoints guaranteed around host calls, allocation-heavy operations, and loop back-edges? - -### Q7. Determinism boundary - -- Which behaviors must be identical across conforming implementations? -- Which details may vary as implementation strategy without changing observable behavior? - -## 4. Expected Spec Material - -After discussion, this agenda should directly feed sections of `Dynamic Semantics Specification.md` covering: - -1. execution state and step ordering, -2. evaluation order by construct, -3. abrupt completion and trap propagation, -4. host-call interaction constraints, -5. determinism requirements for conforming runtimes. - -## 5. Non-Goals - -- Revisiting grammar or typing unless the current surface is impossible to specify dynamically. -- Defining diagnostics wording in detail. -- Designing allocator APIs or collection libraries. - -## 6. Inputs - -- `1. Language Charter.md` -- `3. Core Syntax Specification.md` -- `4. Static Semantics Specification.md` -- `Heap Model - Agenda.md` diff --git a/docs/pbs/agendas/Heap Model - Agenda.md b/docs/pbs/agendas/Heap Model - Agenda.md deleted file mode 100644 index 3dc37efb..00000000 --- a/docs/pbs/agendas/Heap Model - Agenda.md +++ /dev/null @@ -1,89 +0,0 @@ -# PBS Heap Model - Agenda - -Status: Working umbrella agenda (pre-spec) -Purpose: coordinate the PBS discussions that define runtime-visible allocation, lifetime, and heap/host boundaries - -## 1. Context - -Legacy PBS experiments used explicit RC/HIP syntax (`alloc`, `borrow`, `mutate`, `peek`, `take`, `weak`). -Current runtime authority is GC-based with deterministic safepoints. - -The original heap agenda proved too broad because the open questions now span three different but coupled areas: - -- observable execution behavior, -- effect/control surfaces (`optional`, `result`, `apply`, `bind`, `switch`), -- memory ownership, GC, and host-memory boundaries. - -This file now acts as the umbrella agenda that keeps those discussions aligned instead of trying to close every detail in one pass. - -## 2. Agenda Split - -The work is split into the following dedicated agendas: - -1. `Dynamic Semantics - Execution Model Agenda.md` -2. `Dynamic Semantics - Effect Surfaces Agenda.md` -3. `Memory and Lifetime - Agenda.md` - -The heap model is still the cross-cutting reference because allocation visibility, traps, and host boundaries must line up across all three. - -## 3. Cross-Agenda Decisions This Umbrella Owns - -This umbrella must keep the following decisions coherent across the child agendas: - -1. GC is the baseline runtime model for PBS core unless a future profile explicitly says otherwise. -2. Core v1 does not require explicit lifetime syntax for ordinary user code. -3. Deterministic execution and `FRAME_SYNC` constraints override ergonomics when the two conflict. -4. Runtime-visible costs must be surfaced through diagnostics/tooling when code allocates, copies, crosses the host boundary, or can trap. -5. The VM heap and host-owned memory must remain distinct in the user model even when APIs make the boundary feel ergonomic. - -## 4. Questions That Must Stay Aligned - -### Q1. Baseline runtime authority - -- Is GC always the default execution model for PBS core? (expected: yes) -- Which safepoints are part of the observable contract versus implementation detail? - -### Q2. Language vs library boundary - -- Which old RC/HIP concepts stay reserved-only in core syntax? -- Which advanced workflows move to stdlib/tooling APIs rather than language keywords? - -### Q3. Cost visibility contract - -- Which allocations, copies, host transfers, and trap paths must be visible in diagnostics? -- Which cost facts are normative, and which remain profiler-quality best effort? - -### Q4. Host boundary - -- How does PBS communicate "VM heap vs host-owned memory" without exposing raw host pointers as ordinary user values? -- Which host operations are allowed to allocate or retain memory, and how must that appear to the user? - -### Q5. Migration policy - -- What is the official migration story from legacy RC/HIP concepts? -- What hard criteria must be met before any reserved lifetime keyword can be activated in a future profile? - -## 5. Expected Output Documents - -After the child agendas close, use their decisions to draft: - -1. `Dynamic Semantics Specification.md` -2. `Memory and Lifetime Specification.md` -3. `Diagnostics Specification.md` - -The existing `4. Static Semantics Specification.md` may receive follow-up clarifications where memory or effect rules need stronger static wording. - -## 6. Non-Goals for This Umbrella Agenda - -- Defining new VM opcodes. -- Reintroducing RC as mandatory runtime strategy. -- Designing full stdlib memory-management APIs in this pass. -- Settling backend/lowering internals that do not affect observable semantics. - -## 7. Working Assumptions - -1. GC remains baseline for PBS core. -2. Explicit heap control is opt-in and likely library/tooling-driven. -3. Deterministic behavior and frame-sync constraints are non-negotiable. -4. Language should expose cost signals without forcing expert-only syntax. -5. Child agendas may narrow terminology, but they must not conflict on runtime-observable behavior. diff --git a/docs/pbs/agendas/Memory and Lifetime - Agenda.md b/docs/pbs/agendas/Memory and Lifetime - Agenda.md deleted file mode 100644 index 4b4ebdfd..00000000 --- a/docs/pbs/agendas/Memory and Lifetime - Agenda.md +++ /dev/null @@ -1,94 +0,0 @@ -# Memory and Lifetime - Agenda - -Status: Working agenda (pre-spec) -Purpose: define the authoritative PBS memory, ownership, and lifetime model for v1 - -## 1. Context - -PBS no longer exposes the old RC/HIP syntax as active core language, but the language still needs a precise memory story. -That story must explain: - -- what values live on the VM heap, -- what identity and aliasing mean, -- how baseline GC interacts with deterministic execution, -- where host-owned memory begins and ends, -- how allocation and copy costs become visible to advanced users. - -Without this agenda, the future `Memory and Lifetime Specification.md` would not have a stable scope. - -## 2. Decisions to Produce - -This agenda must end with decisions for: - -1. The value-category map: stack-like transient values, heap-backed values, callbacks, collections, and host-backed handles. -2. The lifetime and reachability model under baseline GC. -3. The VM heap vs host-memory boundary and the user-visible rules at that boundary. -4. The minimum cost/allocation visibility contract needed by diagnostics and profiling. -5. The migration and reservation policy for legacy RC/HIP concepts. - -## 3. Core Questions - -### Q1. Heap residency by value category - -- Which core values are heap-backed in v1: structs, callbacks, collections, tuples, `optional`, `result`, or only some of them? -- When a value is assigned, passed, or returned, what is copied versus what aliases the same heap identity? - -### Q2. Identity and aliasing - -- Which user-visible value kinds have stable identity? -- Are struct values always reference-like at runtime even when their fields are small and copyable? -- How should aliasing be described for beginner-facing semantics without hiding performance consequences? - -### Q3. Baseline GC contract - -- Which GC properties are normative: reachability, eventual reclamation, safepoints, no user finalizers? -- Which GC timing details remain non-normative implementation choices? -- Can user code observe reclamation directly, or only via indirect performance/diagnostic signals? - -### Q4. Host memory boundary - -- How are host-backed resources represented in PBS user space: opaque handles, nominal structs, services, or reserved host-bound values? -- Can host memory outlive PBS references, and if yes, what runtime contract prevents unsoundness? -- Is pinning, borrowing, or zero-copy transfer exposed in v1 at all? - -### Q5. Allocation visibility - -- Which operations are allowed to allocate on the VM heap? -- Which host calls may allocate host memory or retain VM-reachable references? -- What must tooling report as allocation, retention, copy, or escape risk? - -### Q6. Lifetime-related traps and safety - -- Which memory problems are impossible by construction in v1 core? -- Which remaining failures become traps, capability rejection, or host-defined status outcomes? - -### Q7. Future explicit control - -- Should pools, arenas, object reuse, or weak-reference patterns exist only as stdlib/tooling surfaces? -- What criteria must be met before reserved keywords like `alloc`, `borrow`, `take`, or `weak` can become active in a future profile? - -## 4. Expected Spec Material - -After discussion, this agenda should directly feed sections of `Memory and Lifetime Specification.md` covering: - -1. runtime memory spaces, -2. value representation classes, -3. identity, aliasing, and copy rules, -4. GC and safepoint guarantees, -5. host-memory boundary rules, -6. cost visibility hooks for `Diagnostics Specification.md`. - -## 5. Non-Goals - -- Defining exact GC algorithm internals. -- Designing complete stdlib pool/arena APIs. -- Reintroducing mandatory user-authored lifetime syntax in core v1. - -## 6. Inputs - -- `1. Language Charter.md` -- `3. Core Syntax Specification.md` -- `4. Static Semantics Specification.md` -- `Heap Model - Agenda.md` -- `Dynamic Semantics - Execution Model Agenda.md` -- `Dynamic Semantics - Effect Surfaces Agenda.md` diff --git a/docs/pbs/decisions/Allocation and Cost Visibility Decision.md b/docs/pbs/decisions/Allocation and Cost Visibility Decision.md new file mode 100644 index 00000000..233654d8 --- /dev/null +++ b/docs/pbs/decisions/Allocation and Cost Visibility Decision.md @@ -0,0 +1,154 @@ +# Allocation and Cost Visibility Decision + +Status: Accepted +Cycle: Initial allocation-and-cost closure pass + +## 1. Context + +PBS v1 needs a minimal but explicit contract for which runtime cost facts matter semantically and which belong only to diagnostics/profiling quality. + +Earlier decisions already fixed important inputs: + +- `bind(context, fn_name)` has real retention/storage consequences, +- `optional`, `result`, `handle`, `!`, `if`, and `switch` are not intended to hide implicit allocation semantics, +- host/userland interaction is stack-only across the boundary, +- and value categories already distinguish copied payload from preserved aliasing. + +## 2. Decision + +PBS v1 adopts the following cost-visibility baseline: + +1. The normatively relevant cost facts are: + - whether an operation may allocate VM-owned runtime storage, + - whether an operation retains state beyond the current evaluation, + - whether an operation copies payload versus preserves aliasing, + - whether an operation crosses the host boundary, + - and whether an operation may trap. +2. `bind(context, fn_name)` is normatively retention-bearing and requires runtime storage sufficient to keep the callback target and captured context alive. +3. `apply` is not allocation-bearing by itself. +4. `optional`, `result`, `handle`, `!`, `if`, and `switch` are not allocation-bearing by themselves. +5. Host-boundary crossing is a normatively relevant cost fact, but concrete host-side allocation details belong to subsystem-specific contracts rather than to a general PBS rule. +6. Quantitative reporting such as exact byte counts, exact object counts, or precise collector timing is not a normative language guarantee in v1. + +## 3. Normatively Relevant Cost Facts + +The following cost facts are part of the PBS semantic model and may be relied on by later tooling/spec work: + +- VM allocation-bearing versus non-allocation-bearing behavior, +- retention-bearing versus non-retention-bearing behavior, +- copy versus aliasing preservation, +- host-boundary crossing, +- trap possibility. + +These facts matter because they affect how advanced tooling, diagnostics, and performance reasoning should interpret a construct. + +## 4. `bind` + +`bind(context, fn_name)` is the strongest closed cost case in the current PBS core. + +Rules: + +- `bind` is not semantically free, +- `bind` is retention-bearing, +- `bind` requires runtime storage sufficient to preserve the callback target and captured context, +- the captured context remains alive while the callback value remains alive. + +This decision does not require the spec to freeze the exact runtime layout used to implement that storage. + +## 5. Non-Allocation-Bearing Surfaces + +The following constructs are not allocation-bearing by themselves in PBS v1: + +- `optional` +- `result` +- `handle` +- `!` +- `if` +- `switch` +- `apply` + +If allocation or retention occurs while evaluating one of these constructs, that cost arises from: + +- subexpression evaluation, +- called targets, +- payload formation already defined elsewhere, +- or runtime behavior outside the surface itself. + +## 6. Copy Versus Aliasing + +Copy versus aliasing is a normatively relevant cost fact. + +The language already distinguishes: + +- pure values copied by value, +- identity-bearing values passed by preserved aliasing, +- carriers that preserve the semantics of their contained values. + +Tooling and later specs may rely on these distinctions even if PBS v1 does not require a warning at every such site. + +## 7. Host Boundary + +Crossing the host boundary is a normatively relevant cost fact. + +However, this decision does not impose a universal rule for: + +- host-side allocation volume, +- host-side object count, +- or host-side retention internals. + +Those details belong to subsystem-specific contracts when and if they become relevant. + +## 8. Normative Versus Best-Effort Reporting + +### 8.1 Normative facts + +The following facts are normative and may be surfaced by diagnostics/tooling: + +- whether a construct is retention-bearing, +- whether a construct crosses the host boundary, +- whether semantics preserve aliasing or copy payload, +- whether a construct may trap. + +### 8.2 Best-effort facts + +The following facts are not normative language guarantees in v1: + +- exact byte counts, +- exact object counts, +- exact collector timing, +- exact host-side allocation volume, +- precise performance ranking beyond the semantic facts above. + +These may be surfaced by implementations as profiling or tooling enrichment, but they are not part of the core language contract. + +## 9. Invariants + +- The language must not imply hidden allocation semantics where none were intentionally specified. +- `bind` remains the canonical retention-bearing callback-forming construct in v1. +- Cost visibility must be strong enough for advanced tooling without forcing exact runtime accounting into the language spec. +- Host-boundary cost reporting must not pretend to know subsystem-specific runtime internals unless those are explicitly specified. + +## 10. Explicit Non-Decisions + +This decision record does not yet close: + +- the final diagnostics wording for warnings or notes, +- subsystem-specific host cost contracts, +- precise collection/profiling metrics, +- optimizer-facing reporting policy. + +## 11. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/10. Memory and Lifetime Specification.md` +- `docs/pbs/specs/11. Diagnostics Specification.md` + +## 12. Validation Notes + +The intended split is: + +- semantic cost facts are explicit, +- `bind` is the main retained-storage construct already closed, +- most other core surfaces are not allocation-bearing by themselves, +- and quantitative performance reporting remains tooling-quality rather than normative language behavior. diff --git a/docs/pbs/decisions/Dynamic Semantics - Branch Selection Decision.md b/docs/pbs/decisions/Dynamic Semantics - Branch Selection Decision.md new file mode 100644 index 00000000..467d4797 --- /dev/null +++ b/docs/pbs/decisions/Dynamic Semantics - Branch Selection Decision.md @@ -0,0 +1,128 @@ +# Dynamic Semantics - Branch Selection Decision + +Status: Accepted +Cycle: Initial branch-selection closure pass + +## 1. Context + +PBS v1 needs a closed runtime contract for `if` and `switch` before the dynamic semantics spec can be completed. + +The remaining questions were: + +- whether conditions and selectors are evaluated once, +- whether non-selected branches evaluate at all, +- which selector categories are admitted for `switch`, +- and whether branch selection itself may trap. + +## 2. Decision + +PBS v1 adopts the following branch-selection rules: + +1. `if` evaluates its condition exactly once. +2. `switch` evaluates its selector exactly once. +3. Only the selected branch or arm executes. +4. Non-selected branches and arms perform no evaluation. +5. `if` and `switch` are trap-free by themselves; only selected subexpressions may trap. +6. `switch` is limited to statically discriminable selector categories. +7. `switch` does not accept `result`, `error`, structs, string objects, or heap-backed types as selectors in v1. + +## 3. `if` + +For: + +```text +if cond { then_block } else { else_block } +``` + +the runtime behaves as follows: + +1. evaluate `cond` exactly once, +2. if it yields `true`, execute only `then_block`, +3. if it yields `false`, execute only `else_block`. + +The non-selected branch is not evaluated, even partially. + +Any trap associated with `if` arises only from: + +- evaluating `cond`, +- or executing the selected branch. + +## 4. `switch` + +### 4.1 Selector evaluation + +For: + +```text +switch selector { ... } +``` + +the runtime: + +1. evaluates `selector` exactly once, +2. determines the matching arm using the canonical matching rule for the selector category, +3. executes exactly one selected arm. + +No non-selected arm is evaluated. + +### 4.2 Admitted selector categories + +In v1, `switch` is restricted to selector categories with static, deterministic matching behavior. + +These include: + +- literal-comparable scalar values, +- enum values, +- `str` values with canonical static identity, +- and other compile-time-constant-compatible selector categories only if explicitly admitted elsewhere. + +`switch` does not accept: + +- `result` values, +- `error` values, +- structs, +- string object/reference types distinct from canonical `str`, +- or heap-backed selector categories. + +Dynamic or structural matching belongs to a future `match`-style construct rather than to `switch`. + +### 4.3 Matching rule + +`switch` arm selection is exact and deterministic for the admitted selector type. + +- Enum selectors match by canonical enum-case identity. +- Scalar selectors match by the exact equality rule already defined for that scalar category. +- `str` selectors match by canonical static string identity rather than by heap-object comparison. + +`switch` does not perform structural matching, guard evaluation, or user-defined equality dispatch. + +## 5. Invariants + +- `if` and `switch` never evaluate more than one branch or arm. +- Branch selection is deterministic for the same selector value. +- `switch` remains a static discriminant-selection construct, not a result/error-processing construct. +- Error processing with logic belongs to `handle`, not to `switch`. + +## 6. Explicit Non-Decisions + +This decision record does not yet close: + +- the final future design of `match`, +- whether additional scalar-like selector categories will be admitted later, +- the complete memory/cost wording associated with selector evaluation. + +## 7. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/9. Dynamic Semantics Specification.md` +- `docs/pbs/specs/4. Static Semantics Specification.md` +- `docs/pbs/specs/3. Core Syntax Specification.md` + +## 8. Validation Notes + +The intended split is: + +- `if` and `switch` perform static, deterministic branch selection, +- `handle` processes modeled `result` errors, +- future dynamic or structural branching belongs to `match`, not to `switch`. diff --git a/docs/pbs/decisions/Dynamic Semantics - Effect Surfaces Decision.md b/docs/pbs/decisions/Dynamic Semantics - Effect Surfaces Decision.md new file mode 100644 index 00000000..fff867da --- /dev/null +++ b/docs/pbs/decisions/Dynamic Semantics - Effect Surfaces Decision.md @@ -0,0 +1,355 @@ +# Dynamic Semantics - Effect Surfaces Decision + +Status: Accepted +Cycle: Initial effect-surfaces closure pass + +## 1. Context + +PBS v1 already commits to several effect and control surfaces in syntax and static semantics, but their runtime behavior must be closed before normative dynamic semantics can be written. + +This decision record captures the first closed subset of that work: + +- `optional`, +- `result`, +- `!` propagation, +- `handle` processing. + +Allocation, retention, copy visibility, and heap-facing cost wording are delegated to the memory and heap decision track. + +## 2. Decision + +PBS v1 adopts the following baseline runtime rules for `optional` and `result` surfaces: + +1. `optional` is a runtime presence/absence carrier with canonical `some(payload)` and `none` states. +2. `some(expr)` evaluates `expr` eagerly and exactly once before forming the `some` carrier. +3. `opt else fallback` evaluates the left operand exactly once and evaluates `fallback` only when the left operand is `none`. +4. `optional` is trap-free by itself; only subexpression evaluation may trap. +5. `result` is the runtime carrier for expected, modelable failure in function return flow. +6. `expr!` evaluates `expr` exactly once and performs immediate enclosing-function error propagation on failure. +7. `handle expr { ... }` evaluates `expr` exactly once and, on error, executes exactly one matching arm. +8. A `handle` arm may execute user-defined logic. +9. A `handle` arm must terminate with either `ok(payload)` or `err(E2.case)`. +10. `ok(payload)` in a `handle` arm recovers locally and yields the payload as the value of the `handle` expression. +11. `err(E2.case)` in a `handle` arm performs immediate enclosing-function return with that error. +12. `handle` supports a short remap form `E1.case -> E2.case` as sugar for a block that returns `err(E2.case)`. +13. Neither `!` nor `handle` intercepts or converts traps. +14. `apply` is the canonical universal call surface for PBS v1 across all callable categories. +15. `apply` chains parse right-associatively but preserve the already-closed left-to-right observable evaluation model. +16. `apply` does not introduce implicit composition of `optional` or `result` surfaces. +17. `bind(context, fn_name)` forms a nominal callback value by attaching a struct context to a top-level function target. +18. `bind` evaluates its context expression exactly once, captures the same runtime context identity without copying it, and injects that context as the first argument when the callback is invoked. +19. `bind` is not a general closure mechanism and is trap-free at the language level. + +## 3. `optional` + +### 3.1 Runtime model + +`optional` has exactly two runtime states: + +- `some(payload)` +- `none` + +`none` is the canonical absence of payload. + +### 3.2 Construction + +`some(expr)`: + +- evaluates `expr` eagerly, +- evaluates it exactly once, +- then forms the `some(payload)` carrier from the produced payload. + +### 3.3 Extraction + +`opt else fallback`: + +1. evaluates `opt` exactly once, +2. if the result is `some(payload)`, yields the extracted payload and does not evaluate `fallback`, +3. if the result is `none`, evaluates `fallback` and yields that value. + +`else` is extraction with fallback, not error handling. + +### 3.4 Trap behavior + +`optional` itself does not trap. + +Any trap associated with `some(expr)` or `opt else fallback` arises only from: + +- evaluating `expr`, +- evaluating the left operand, +- or evaluating the fallback when it is needed. + +## 4. `result` + +### 4.1 Runtime role + +`result` is the runtime carrier for success-or-modeled-failure at function boundaries and in expressions whose static type is `result P`. + +In v1, `ok(...)` and `err(...)` are special result-flow forms. + +They are not general-purpose first-class userland constructors for arbitrary data modeling. + +They are valid in: + +- function return flow for `result`, +- and `handle` arms, where they control recovery or propagation. + +### 4.2 `!` propagation + +`expr!`: + +1. evaluates `expr` exactly once, +2. if `expr` yields success, yields the extracted success payload as the value of the expression, +3. if `expr` yields error, performs immediate enclosing-function return with the same `err(...)`. + +`!` does not: + +- remap the error, +- intercept traps, +- or continue ordinary evaluation after the propagated error path is chosen. + +### 4.3 `handle` + +`handle expr { ... }`: + +1. evaluates `expr` exactly once, +2. if `expr` yields success, yields the extracted success payload directly, +3. if `expr` yields error, selects exactly one matching handle arm, +4. executes the selected arm, +5. requires that arm to terminate with either `ok(payload)` or `err(E2.case)`. + +### 4.4 `handle` arm results + +The selected `handle` arm has two admissible result forms: + +- `ok(payload)` +- `err(E2.case)` + +Their semantics are: + +- `ok(payload)` recovers locally and makes the `handle` expression yield `payload`, +- `err(E2.case)` performs immediate enclosing-function return with `err(E2.case)`. + +The `payload` in `ok(payload)` must be compatible with the success payload shape produced by the surrounding `handle` expression. + +The `E2.case` in `err(E2.case)` must belong to the target error type required by the enclosing context. + +### 4.5 `handle` sugar + +For the common remap-only case, `handle` supports a short arm form: + +```text +E1.case -> E2.case +``` + +This is sugar for: + +```text +E1.case -> { err(E2.case) } +``` + +Recovery with `ok(payload)` requires the explicit block form. + +### 4.6 `handle` scope + +`handle` may execute user-defined logic inside an arm, but it remains specific to modeled `result` errors. + +It does not provide: + +- trap interception, +- arbitrary processing of non-`result` failure channels, +- or a general-purpose exception system. + +## 5. Invariants + +- `optional` models absence, not failure. +- Expected recoverable failure remains in `result`, not in `optional`. +- `!` is an early-return propagation surface. +- `handle` is a typed result-processing surface with controlled recovery or propagation. +- Success paths produce payload values directly. +- Error paths in `result` remain explicit and typed. +- Trap remains outside ordinary recoverable error flow. +- `apply` remains the single semantic call surface even when user code uses direct-call sugar. +- Callable-specific dispatch differences do not change the user-visible call pipeline. +- Effect boundaries remain explicit; `apply` does not auto-lift through `optional` or `result`. + +## 6. `apply` + +### 6.1 Canonical role + +`apply` is the canonical universal call surface in PBS v1. + +Direct call syntax is only sugar over `apply` and does not define separate runtime semantics. + +The same observable call model applies to: + +- top-level functions, +- struct methods, +- service methods, +- contract calls, +- callback calls, +- host-backed calls. + +### 6.2 Shared observable pipeline + +For `lhs apply rhs`, the shared observable runtime pipeline is: + +1. form the call target from `lhs`, +2. evaluate any receiver or callable artifact needed for target formation exactly once, +3. evaluate `rhs` exactly once, +4. invoke the resolved target, +5. produce one of: + - normal return, + - explicit `result` propagation, + - or `trap`. + +Callable-specific dispatch strategy may differ internally, but it does not change this user-visible sequencing model. + +### 6.3 Chained `apply` + +`apply` chains are parsed right-associatively. + +For example: + +```text +f1 apply f2 apply f3 apply params +``` + +parses as: + +```text +f1 apply (f2 apply (f3 apply params)) +``` + +The observable evaluation order still follows the already-closed left-to-right model: + +1. form the target of `f1`, +2. evaluate the argument expression for `f1`, +3. within that argument expression, form the target of `f2`, +4. evaluate the argument expression for `f2`, +5. within that argument expression, form the target of `f3`, +6. evaluate `params`, +7. invoke `f3`, +8. invoke `f2`, +9. invoke `f1`. + +### 6.4 Effect boundaries + +`apply` does not introduce implicit effect composition. + +If a callable returns: + +- `optional

`, extraction remains explicit through `else`, +- `result P`, propagation or remapping remains explicit through `!` or `handle`. + +PBS v1 does not auto-lift ordinary call chains through `optional` or `result` boundaries. + +## 7. `bind` + +### 7.1 Role + +`bind(context, fn_name)` is the explicit callback-formation mechanism in PBS v1. + +It exists to attach a struct context to a compatible top-level function without introducing general lexical closures. + +### 7.2 Context and target + +`bind` requires: + +- a context expression whose runtime value is a struct instance, +- a top-level function target whose first parameter is compatible with that struct type, +- and an expected callback type already validated by static semantics. + +### 7.3 Runtime artifact + +`bind(context, fn_name)` produces a nominal callback value that stores: + +- the resolved top-level function target, +- the captured runtime identity of the context value. + +The context is not copied or rematerialized during binding. + +When the callback is later invoked, the runtime behaves as if it calls: + +```text +fn_name(context, ...) +``` + +where `context` is the same captured runtime instance. + +### 7.4 Evaluation and identity + +The context expression is evaluated exactly once at bind time. + +That evaluation exists only to obtain the struct instance that will be attached to the callback. + +After capture: + +- the same runtime context identity remains attached, +- mutations performed through the callback observe and affect that same context instance, +- `bind` does not create a detached copy of the context. + +### 7.5 Storage and retention + +`bind` is not semantically free. + +Forming a callback through `bind` requires runtime storage sufficient to keep: + +- the callback target identity, +- and the captured context alive while the callback value remains alive. + +For the purposes of PBS v1 semantics, `bind` should be treated as a callback-forming operation with real retention and heap-facing consequences, even though the final memory/lifetime wording belongs in the dedicated memory specification. + +### 7.6 Trap behavior + +At the language-semantics level, `bind` is trap-free. + +Incompatible context type, incompatible function target, or invalid callback shape are compile-time errors rather than runtime traps. + +`bind` introduces no ordinary recoverable error surface and no bind-specific trap surface. + +### 7.7 Non-goal + +`bind` is not: + +- general closure capture, +- arbitrary local-environment capture, +- or a promise that future closure features must behave identically. + +It is the explicit v1 callback-binding mechanism only. + +## 8. Explicit Non-Decisions + +This decision record does not yet close: + +- the final memory/lifetime wording for allocation, copy, and retention visibility, +- the final catalog of trap sources that may arise from subexpression evaluation. + +## 9. 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/pbs/specs/11. Diagnostics Specification.md` + +The unresolved cost and retention wording for these surfaces should be completed through: + +- `docs/pbs/agendas/Memory and Lifetime - Agenda.md` +- `docs/pbs/agendas/Heap Model - Agenda.md` + +## 10. Validation Notes + +The intended behavior is: + +- `some(expr)` is eager, +- `opt else fallback` is short-circuit on `some`, +- `!` propagates the same typed error unchanged, +- `handle` remaps typed errors without introducing custom logic, +- `apply` remains the universal call surface across callable kinds, +- chained `apply` does not create implicit optional/result composition, +- `bind` captures a struct context identity without copying it, +- `bind` forms a callback with real retention/storage consequences, +- `handle` may recover with `ok(payload)` or propagate with `err(E2.case)`, +- short-form `handle` arms are sugar for propagation-only remap blocks, +- `trap` remains outside both `!` and `handle`. diff --git a/docs/pbs/decisions/Dynamic Semantics - Execution Model Decision.md b/docs/pbs/decisions/Dynamic Semantics - Execution Model Decision.md new file mode 100644 index 00000000..c03e872c --- /dev/null +++ b/docs/pbs/decisions/Dynamic Semantics - Execution Model Decision.md @@ -0,0 +1,131 @@ +# Dynamic Semantics - Execution Model Decision + +Status: Accepted +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` 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`, 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` propagation, + - or `trap`. + +This rule applies to canonical `apply` and to ordinary call sugar that desugars to `apply`. + +## 5. Error Boundary + +`result` and `trap` are distinct runtime categories. + +### 5.1 `result` + +`result` 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` 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` failure. +- Host-backed operations must expose predictable operational failures through `result` 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/pbs/specs/16. Runtime Execution and Initialization Specification.md` + +It should also constrain future work in: + +- `docs/pbs/specs/11. Diagnostics Specification.md` +- `docs/pbs/specs/13. Conformance Test Specification.md` + +## 9. Validation Notes + +The intended rule is: + +- expected domain failure: `result` +- remappable, processable, or propagatable failure: `result` +- 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. diff --git a/docs/pbs/decisions/GC and Reachability Decision.md b/docs/pbs/decisions/GC and Reachability Decision.md new file mode 100644 index 00000000..2419a57c --- /dev/null +++ b/docs/pbs/decisions/GC and Reachability Decision.md @@ -0,0 +1,130 @@ +# GC and Reachability Decision + +Status: Accepted +Cycle: Initial GC-and-reachability closure pass + +## 1. Context + +PBS v1 uses GC as the baseline runtime model, but the language still needs a precise statement of: + +- what reachability guarantees are normative, +- what reclamation guarantees are normative, +- what remains implementation-defined, +- how GC interacts with the single normative safepoint at `FRAME_SYNC`, +- and what user code may or may not observe. + +## 2. Decision + +PBS v1 adopts the following GC-and-reachability baseline: + +1. GC is the baseline runtime model for VM-owned memory in PBS core. +2. Reachability is the normative liveness criterion for GC-managed values. +3. Eventual reclamation is the strongest reclamation guarantee in v1. +4. `FRAME_SYNC` is the only normative safepoint relevant to GC-observable behavior. +5. User code cannot observe reclamation directly. +6. PBS v1 defines no user-authored finalizers, destructors, or reclamation callbacks. +7. Implementations may perform internal GC work outside `FRAME_SYNC` only if doing so creates no additional user-visible semantic effects. + +## 3. Normative Reachability Contract + +For GC-managed VM-owned values, liveness is defined by reachability from the runtime roots that matter to PBS semantics. + +At minimum, these roots include: + +- currently active local/frame state, +- reachable fields of reachable struct instances, +- service singleton roots, +- retained callback state that remains reachable, +- and any other runtime roots required to preserve already-observable PBS behavior. + +If a GC-managed value remains reachable through the normative runtime state, the implementation must preserve its continued semantic availability. + +If a value becomes unreachable, user code must not rely on when reclamation occurs. + +## 4. Reclamation Guarantee + +PBS v1 guarantees eventual reclamation, not prompt reclamation. + +This means: + +- unreachable GC-managed memory may be reclaimed later, +- the language does not promise immediate reclamation, +- the language does not promise reclamation at a specific frame boundary, +- and the language does not expose a semantic event when reclamation occurs. + +## 5. Safepoint Relationship + +`FRAME_SYNC` is the only normative safepoint in PBS v1. + +For GC semantics, this means: + +- the language does not promise any additional observable GC safepoints, +- no user-visible program rule may depend on another safepoint existing, +- and any internal collector work outside `FRAME_SYNC` must remain semantically invisible to PBS userland. + +The spec does not require a specific collector architecture. +It only constrains what may become observable. + +## 6. Observability + +User code cannot observe reclamation directly. + +PBS v1 provides no user-visible mechanism for: + +- detecting that a value was collected, +- registering a callback on reclamation, +- forcing immediate collection, +- or sequencing user code against GC timing. + +GC-related information may appear in diagnostics, profiling, or runtime tooling, but those surfaces are not ordinary language semantics. + +## 7. Finalization and Cleanup + +PBS v1 forbids user-authored finalizers and destructor-like reclamation hooks. + +GC reclamation of pure VM-owned values does not trigger user code. + +Host-backed cleanup policy is not defined by GC finalization semantics in this decision. +If host-backed resources require explicit or contract-specific cleanup rules, those belong to the host-boundary decision track rather than to GC finalization in userland. + +## 8. Invariants + +- Reachability, not timing, is the normative semantic axis. +- Reclamation timing remains implementation-defined. +- No direct user-visible behavior is allowed to depend on collector timing. +- The only normative safepoint is `FRAME_SYNC`. +- GC must not create extra user-visible sequencing effects outside the already-closed execution model. + +## 9. Beginner-Facing Model + +The user-facing explanation should be: + +- if a value can still be reached by the program, it remains alive, +- once it can no longer be reached, the runtime may clean it up later, +- the program does not control or directly observe that cleanup moment. + +## 10. Explicit Non-Decisions + +This decision record does not yet close: + +- the exact collector algorithm, +- host-backed resource cleanup semantics, +- diagnostics wording for GC-related tooling surfaces, +- the full root-set wording as finally integrated into the memory specification. + +## 11. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/10. Memory and Lifetime Specification.md` +- `docs/pbs/specs/11. Diagnostics Specification.md` +- `docs/pbs/specs/16. Runtime Execution and Initialization Specification.md` + +## 12. Validation Notes + +The intended split is: + +- GC defines reachability and eventual reclamation, +- `FRAME_SYNC` is the only normative safepoint, +- reclamation timing is not user-observable, +- host-backed cleanup is a separate boundary question rather than a user finalization feature. diff --git a/docs/pbs/decisions/Host Memory Boundary Decision.md b/docs/pbs/decisions/Host Memory Boundary Decision.md new file mode 100644 index 00000000..114bd698 --- /dev/null +++ b/docs/pbs/decisions/Host Memory Boundary Decision.md @@ -0,0 +1,115 @@ +# Host Memory Boundary Decision + +Status: Accepted +Cycle: Initial host-boundary closure pass + +## 1. Context + +PBS needs a user-visible contract for the boundary between VM-owned semantics and host-provided runtime services. + +At the current stage of the language, userland does not expose complex host-owned resource models. +The runtime offers features and the frontend consumes them; PBS should be careful not to project unnecessary language-level memory abstractions into runtime internals too early. + +## 2. Decision + +PBS v1 adopts the following host-memory boundary baseline: + +1. Cross-boundary interaction between host and PBS userland is restricted to stack-only values. +2. PBS userland does not expose host memory as ordinary language values. +3. Raw pointers are not exposed in PBS userland. +4. Borrowed host-memory views are not exposed in PBS userland. +5. Pinning is not exposed in PBS v1. +6. Zero-copy transfer is not exposed in PBS v1. +7. Heap-shared boundary values between host and PBS userland are not part of the v1 model. +8. Long-lived host resources, if later exposed, must be specified explicitly by subsystem contract rather than inferred from a general host-memory model. + +## 3. Boundary Rule + +The host/userland boundary in PBS v1 is value-based rather than memory-sharing-based. + +This means: + +- host-backed interaction happens through explicit call boundaries, +- data crossing that boundary is limited to stack-only value forms, +- and userland never receives direct access to host-owned memory regions. + +PBS therefore does not model host memory as something the language can directly hold, borrow, pin, or traverse. + +## 4. What Is Not Exposed + +PBS v1 does not expose any general userland model for: + +- raw host pointers, +- borrowed host slices or views, +- pinned host memory, +- zero-copy host/userland transfer, +- shared heap objects spanning host memory and VM memory. + +These features are out of scope for the v1 language model. + +## 5. Role of Syscalls + +At the current stage, host interaction should be understood primarily through syscall-style host-backed contracts. + +Those contracts may accept and return stack-only values, but they do not imply that PBS userland owns, borrows, or directly manipulates host memory. + +## 6. Long-Lived Host Resources + +PBS v1 does not yet define a general-purpose language model for long-lived host-owned resources such as: + +- banks, +- mixers, +- or other subsystem-specific retained resources. + +If such resources are exposed later, they must be specified by explicit subsystem contract rather than by assuming a general host-memory-handle model in core PBS. + +## 7. Failure Model Scope + +This decision does not force a universal language-level error projection for all runtime-internal host behavior. + +It only closes the memory-boundary side of the question: + +- PBS userland does not directly manipulate host memory, +- and cross-boundary interaction remains stack-value-based. + +Concrete error modeling for particular host-backed surfaces belongs to the contract of those surfaces rather than to a general raw-memory boundary rule. + +## 8. Invariants + +- The host/runtime may own internal memory and resource lifetimes that PBS userland never sees directly. +- PBS userland remains insulated from host-memory unsoundness by not exposing raw memory access at the language level. +- The absence of pointers and borrowed host views is a core v1 safety property. +- Boundary simplicity takes priority over premature expressiveness in this area. + +## 9. Beginner-Facing Model + +The user-facing explanation should be: + +- the runtime can provide services to PBS programs, +- programs pass ordinary values into those services and receive ordinary values back, +- but programs do not directly hold or manipulate host memory. + +## 10. Explicit Non-Decisions + +This decision record does not yet close: + +- the future design of subsystem-specific long-lived host resources, +- the future design of any explicit resource-release APIs, +- the concrete error contract of each host-backed surface, +- the final wording of host-boundary diagnostics. + +## 11. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/10. Memory and Lifetime Specification.md` +- `docs/pbs/specs/6. VM-owned vs Host-backed.md` +- `docs/pbs/specs/6.2. Host ABI Binding and Loader Resolution Specification.md` + +## 12. Validation Notes + +The intended split is: + +- runtime and host internals may remain complex, +- PBS userland sees only stack-only value exchange across the boundary, +- and any richer host-resource model must be introduced later by explicit subsystem contract. diff --git a/docs/pbs/decisions/Lifetime Control and Future Profiles Decision.md b/docs/pbs/decisions/Lifetime Control and Future Profiles Decision.md new file mode 100644 index 00000000..3c65a614 --- /dev/null +++ b/docs/pbs/decisions/Lifetime Control and Future Profiles Decision.md @@ -0,0 +1,121 @@ +# Lifetime Control and Future Profiles Decision + +Status: Accepted +Cycle: Initial lifetime-control policy closure pass + +## 1. Context + +PBS v1 no longer uses the old RC/HIP model as an active core-language direction. + +The remaining question is not how to design explicit lifetime control now, but how the project should treat legacy concepts and what policy should govern any future reintroduction of lifetime-oriented language features. + +## 2. Decision + +PBS v1 adopts the following lifetime-control policy baseline: + +1. No lifetime-control keyword is reserved in core PBS merely for possible future use. +2. If a lifetime-control surface is not active in v1, it should not remain in the language as a reserved future-only keyword on that basis alone. +3. Advanced memory workflows should default to library/tooling-first exploration rather than syntax-first activation. +4. GC remains the default core model; future explicit lifetime control, if ever introduced, must be profile-gated rather than silently folded into the default language. +5. Future lifetime-oriented syntax may be introduced only when there is concrete evidence that library/tooling approaches are insufficient. + +## 3. Legacy RC/HIP Concepts + +Legacy concepts such as: + +- `alloc` +- `borrow` +- `take` +- `weak` +- pool-style and arena-style control patterns +- object reuse patterns + +do not remain active merely by historical inertia. + +For PBS v1 policy: + +- legacy concepts may survive as historical or design-reference material, +- but they do not imply reserved syntax commitment, +- and they do not imply a roadmap promise of later activation. + +## 4. Language Versus Library Boundary + +The default policy is: + +- library first, +- tooling first, +- profile later only if justified, +- syntax last. + +This means advanced workflows should first be explored through: + +- stdlib APIs, +- tooling support, +- diagnostics, +- profiling guidance, +- subsystem-specific contracts where needed. + +The language should not absorb explicit lifetime syntax simply because a legacy concept existed before. + +## 5. Migration Narrative + +The official migration narrative is: + +- PBS v1 moves away from RC/HIP-style user-authored lifetime control as the core user model, +- GC plus deterministic execution is the baseline, +- performance-sensitive reasoning remains important, +- but performance and memory control should rise through explicit APIs and tooling before new syntax is considered. + +This is a deliberate simplification, not a temporary placeholder awaiting automatic return to explicit ownership syntax. + +## 6. Future Activation Criteria + +Any future lifetime-oriented language/profile work must satisfy all of the following: + +1. Real implementation and product evidence shows that library/tooling-first approaches are insufficient. +2. The proposed feature has a coherent semantic model that does not break the GC baseline by accident. +3. The feature can be isolated behind an explicit profile or equivalent opt-in boundary. +4. Diagnostics, conformance, and migration obligations are clear. +5. The feature does not degrade the beginner-facing default language without strong justification. + +Future activation must be justified by present need and validated design, not by preserving speculative syntax in the current language. + +## 7. Invariants + +- GC remains the default core runtime model. +- Core PBS v1 does not promise future activation of legacy lifetime syntax. +- Absence of reserved lifetime keywords is a deliberate policy choice. +- Future explicit control must be explicit, justified, and profile-gated. + +## 8. Beginner-Facing Model + +The user-facing explanation should be: + +- PBS v1 does not require ownership or lifetime syntax in ordinary code, +- advanced control is not removed as a future possibility, +- but it will be introduced only if it proves necessary and only through explicit design, not through dormant keywords left in the language. + +## 9. Explicit Non-Decisions + +This decision record does not yet close: + +- the exact shape of any future profile mechanism, +- the exact syntax of any future explicit lifetime feature, +- the future stdlib design for pools, arenas, or weak-reference-like patterns. + +## 10. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/10. Memory and Lifetime Specification.md` +- `docs/pbs/specs/17. Compatibility and Evolution Policy.md` +- `docs/pbs/specs/3. Core Syntax Specification.md` + +## 11. Validation Notes + +The intended policy is: + +- no dormant lifetime keywords in core v1, +- no nostalgia-based reservation policy, +- library/tooling first, +- profile-gated language activation only when clearly justified. diff --git a/docs/pbs/decisions/Value Representation and Identity Decision.md b/docs/pbs/decisions/Value Representation and Identity Decision.md new file mode 100644 index 00000000..12553841 --- /dev/null +++ b/docs/pbs/decisions/Value Representation and Identity Decision.md @@ -0,0 +1,190 @@ +# Value Representation and Identity Decision + +Status: Accepted +Cycle: Initial value-representation closure pass + +## 1. Context + +PBS v1 needs a stable user-visible model for: + +- which values are pure copied payloads, +- which values preserve shared runtime identity, +- which carriers merely wrap other values, +- and how callback values fit into the language without exposing general first-class functions or closures. + +Earlier decisions already fixed important inputs: + +- structs are reference-like in ordinary use, +- services are canonical singleton values, +- `bind(context, fn_name)` captures the same struct identity without copying it, +- `optional` and `result` remain explicit carriers rather than implicit effect-lifting mechanisms. + +## 2. Decision + +PBS v1 adopts the following value-representation baseline: + +1. Pure scalar-like values are copied by value and do not carry user-visible identity. +2. Struct values are identity-bearing, heap-backed reference values. +3. Service values are identity-bearing canonical singleton values. +4. Host-backed resource values are identity-bearing values on the PBS side, even though their backing authority remains host-owned. +5. Tuple, `optional`, and `result` carriers do not introduce identity of their own. +6. Contract values do not introduce a new user-visible identity distinct from the underlying struct or service value. +7. Callback values are first-class callable values in PBS v1, but callback identity is not promoted as a user-visible identity concept. +8. Assignment, parameter passing, and return preserve aliasing for identity-bearing values and copy payload for pure value kinds. + +## 3. Value Categories + +### 3.1 Pure copied values + +The following value kinds are pure copied values in the user model: + +- `int` +- `float` +- `bool` +- enum values +- canonical `str` + +Assignment, parameter passing, and return of these values copy the value itself. + +### 3.2 Identity-bearing values + +The following value kinds carry stable user-visible identity: + +- struct values +- service values +- host-backed resource/handle values + +Assignment, parameter passing, and return of these values preserve aliasing to the same runtime entity rather than copying an independent underlying object. + +### 3.3 Carrier-only values + +The following value kinds are carriers and do not create identity of their own: + +- tuples +- `optional` +- `result` + +They preserve the semantics of the values they contain. + +If a carrier contains an identity-bearing payload, the carrier transports that same payload identity rather than inventing a new one. + +## 4. Structs + +Struct values are always reference-like in PBS v1. + +Rules: + +- `new Struct(...)` produces a fresh struct identity. +- Assignment of a struct value copies the reference, not the underlying field storage. +- Passing or returning a struct value preserves aliasing to the same struct instance. +- Mutation through one alias is observable through other aliases to that same struct instance. + +## 5. Services + +Service values are canonical module-owned singleton values. + +Rules: + +- A service value denotes the same singleton identity wherever it is used in the same resolved program. +- Assignment, parameter passing, and return preserve that same singleton identity. +- Service use does not create fresh service instances. + +## 6. Contract Values + +Contract values do not introduce a new user-visible entity. + +A contract value is a runtime view over: + +- an underlying struct identity or service singleton identity, +- together with the selected contract implementation used for dispatch. + +For user-facing semantics: + +- aliasing is defined by the underlying struct or service value, +- not by treating the contract wrapper as a separate identity-bearing object. + +## 7. Callback Values + +Callback values are first-class callable values in PBS v1. + +This means they may be: + +- assigned to variables, +- passed as arguments, +- and returned from functions. + +However, PBS v1 does not promote callback identity as an explicit user-visible identity concept. + +### 7.1 Plain callback values + +When a callback value is formed from a compatible top-level `fn`, it denotes a callable value over that target function. + +### 7.2 Bound callback values + +When a callback value is formed through `bind(context, fn_name)`: + +- the same struct context identity is captured, +- the context is not copied, +- the callback retains the target function together with that captured context, +- and invoking the callback behaves as if the target function is called with the captured context as its first argument. + +### 7.3 User model + +The language must explain callback behavior without requiring the user to reason about callback identity as if callbacks were ordinary heap objects. + +It is sufficient to state that: + +- callbacks are first-class callable values, +- bound callbacks retain their captured context, +- and copies of a callback value preserve the same callable meaning and retained context. + +## 8. Copy Versus Aliasing Rule + +The general rule for PBS v1 is: + +- pure value kinds are copied by value, +- identity-bearing kinds preserve aliasing, +- carrier kinds preserve the semantics of their contained values and do not create identity of their own. + +Examples: + +- assigning an `int` copies the integer value, +- assigning a `Struct` value copies the reference to the same struct instance, +- assigning an `optional` that contains `some(player)` preserves the same `Player` identity inside the carrier, +- assigning a `result Player` success payload preserves the same `Player` identity inside the carrier. + +## 9. Beginner-Facing Model + +The user-facing explanation should be: + +- some values are plain data, so passing them passes the value, +- structs and services are shared entities, so passing them passes access to the same entity, +- tuples, `optional`, and `result` only package values and do not become new entities by themselves, +- callbacks are callable values, and bound callbacks keep the same captured context rather than copying it. + +This wording is simple enough for beginners while still preserving the performance-relevant truth about aliasing and mutation. + +## 10. Explicit Non-Decisions + +This decision record does not yet close: + +- the exact runtime layout of any heap object, +- collection value categories in detail, +- the final host-backed handle representation syntax, +- the final diagnostics wording for aliasing/copy visibility. + +## 11. Spec Impact + +This decision should feed at least: + +- `docs/pbs/specs/10. Memory and Lifetime Specification.md` +- `docs/pbs/specs/4. Static Semantics Specification.md` +- `docs/pbs/specs/11. Diagnostics Specification.md` + +## 12. Validation Notes + +The intended split is: + +- structs, services, and host-backed resources behave like identity-bearing entities, +- tuples, `optional`, and `result` are carriers, +- callbacks are first-class callable values without promoted callback identity in the user model.