PCD Type System
PCD uses a structural type system with inference. The planner transforms programs into SSA (Static Single Assignment) form before type checking. Types flow through the circuit — the TCE (Thermodynamic Coherence Engine) verifies that types are consistent across all paths before Φ_c = 1 can be certified.PCD does not require explicit type annotations. The planner infers all types from usage. Type errors are caught at compile time, before any code generation.
Primitive Types
i64 — Default Integer
The default integer type in PCD. All integer literals are i64 unless used as monomer arguments (see u8 below):
i64 values use standard 64-bit signed integer semantics. Overflow is not trapped — it wraps.
u8 — Monomer Argument Type
u8 is the type expected by most arithmetic and logic monomers. The planner automatically coerces i64 and bool values to u8 at monomer call boundaries:
u8 coercion is rarely needed — the planner handles it at monomer boundaries. However, control monomers (MC_24–MC_31) are an exception: MC_24.IF requires a bool condition, and the planner preserves bool values for these monomers rather than coercing them to u64.
bool — Boolean
Boolean literals are true and false:
bool is coerced to u8: true → 1, false → 0.
In control monomers (id 24–31), bool is preserved as-is.
Comparison operators produce bool:
bool:
bool/i64 comparisons in CmpEq:
string — UTF-8 Text
Strings are UTF-8 encoded, immutable values:
+ operator is sugar for MC_40.CONCAT:
Composite Types
Array
Arrays are ordered, homogeneous collections. Literal syntax:Array indices must be
i64. Out-of-bounds access produces an error that can be caught with try/catch.Tuple
Tuples are fixed-size heterogeneous collections. They are primarily used for multiple return values:MC_03.DIV8:
Struct
Structs are named product types with labeled fields: Definition:Closures
Closures are first-class function values that capture their enclosing scope:Type Coercion at Monomer Boundaries
The PCD planner applies automatic coercion rules when calling monomers:bool → u8 coercion (Arithmetic/Logic monomers, id 0–15)
bool → u8 coercion (Arithmetic/Logic monomers, id 0–15)
When a
bool is passed to an arithmetic or logic monomer, it is coerced: true → 1, false → 0.bool preservation (Control monomers, id 24–31)
bool preservation (Control monomers, id 24–31)
Control monomers like
MC_24.IF require actual bool values. The planner skips bool → u64 coercion for these monomers.i64 → u8 coercion (all arithmetic monomers)
i64 → u8 coercion (all arithmetic monomers)
i64 values passed to arithmetic monomers are narrowed to u8 (low 8 bits). For values that fit in 0–255 this is lossless.Monomer return type: always Value::I64
Monomer return type: always Value::I64
Regardless of the monomer family, all single-value monomers return
Value::I64. Only MC_03.DIV8 returns Value::Tuple([i64, i64]).SSA Form and the Planner
The PCD planner transforms programs into SSA (Static Single Assignment) form before type checking and optimization. Understanding SSA is important for writing correct loop-carried variables.SSA Versioning
In SSA form, every assignment creates a new version of a variable:Loop-Carried Variables
The planner’sbind_let function always uses version 0 for loop-carried rebindings. This ensures the variable slot is shared across iterations:
Type Inference in SSA
The planner infers types by propagating them through SSA edges:- Literal
42→i64 fn(x, y) { x + y }— parameters are polymorphic until first use;+constrains toi64- Monomer returns → always
i64(except DIV8 →Tuple) true/false→bool[...]→array(element type inferred from contents)(a, b)→Tuple(heterogeneous)
Value Types vs. Reference Semantics
PCD uses value semantics for all types. There are no references or pointers. Passing a struct or array to a function copies the value:Type Summary Table
| Type | Literal Example | Notes |
|---|---|---|
i64 | 42, -7, 0 | Default integer type |
u8 | (coerced from i64) | Used at monomer boundaries |
bool | true, false | Coerced to u8 in arithmetic |
string | "hello" | UTF-8, immutable |
array | [1, 2, 3] | Homogeneous, value semantics |
tuple | (a, b) | Heterogeneous, fixed size |
struct | Point { x: 0, y: 0 } | Named fields, value semantics |
closure | fn(x) { x + 1 } | First-class function value |
Tuple([i64, i64]) | (DIV8 return) | Only from MC_03.DIV8 |