# Value Representation and Identity Decision

Status: Accepted (Implemented)
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<Player>` that contains `some(player)` preserves the same `Player` identity inside the carrier,
- assigning a `result<E> 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/12. 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.
