6.7 KiB
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,optionalandresultremain explicit carriers rather than implicit effect-lifting mechanisms.
2. Decision
PBS v1 adopts the following value-representation baseline:
- Pure scalar-like values are copied by value and do not carry user-visible identity.
- Struct values are identity-bearing, heap-backed reference values.
- Service values are identity-bearing canonical singleton values.
- Host-backed resource values are identity-bearing values on the PBS side, even though their backing authority remains host-owned.
- Tuple,
optional, andresultcarriers do not introduce identity of their own. - Contract values do not introduce a new user-visible identity distinct from the underlying struct or service value.
- Callback values are first-class callable values in PBS v1, but callback identity is not promoted as a user-visible identity concept.
- 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:
intfloatbool- 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
optionalresult
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
intcopies the integer value, - assigning a
Structvalue copies the reference to the same struct instance, - assigning an
optional<Player>that containssome(player)preserves the samePlayeridentity inside the carrier, - assigning a
result<E> Playersuccess payload preserves the samePlayeridentity 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, andresultonly 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.mddocs/pbs/specs/4. Static Semantics Specification.mddocs/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, andresultare carriers, - callbacks are first-class callable values without promoted callback identity in the user model.