plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


cdb6abb — Peter John 2026-11-04T10:44:51+05:30
docs: after FBIP, record merges into an immutable struct with compiler-chosen boxing
docs/decisions/2026-11-language-and-scene-decisions.md CHANGED
@@ -97,6 +97,16 @@ A record of the design decisions taken in the 2026-11-03/04 sessions, with the r
97
97
  - **Why not plain Koka:** Koka checks for a reference count of 1 at runtime (Perceus). Plum's heap is wasm-gc, which has no reference counts, so Plum proves uniqueness statically first. A small reference count used only as a uniqueness check (the GC still frees memory) is the fallback if static proof falls short on the games.
98
98
  - **Risk:** an array write the analysis can't prove unique silently becomes a copy every frame; `fip` turns that into a compile error. The `mut` fields left after the restrictions plan are this plan's worklist.
99
99
 
100
+ ## 9b. After FBIP: one product type, `struct`
101
+
102
+ - **Reasoning:** once FBIP removes mutation, a record's identity can no longer be observed (nothing changes it under you, and `==` becomes structural), so `record` and `struct` mean the same thing, a product of fields, and differ only in memory layout.
103
+ - **Decision (user, 2026-11-04):** merge them into one product type called `struct` (the name already implies an immutable value). `record` goes away.
104
+ - Structs are immutable; updates use spread, `Orb(..o, x: 1.0)`.
105
+ - The compiler chooses the layout: boxed (heap) for recursive types, large values, values holding arrays and values FBIP should update in place; unboxed (inline, arrays stored field by field) for small flat values such as `Vec2`, `Color`, `Pose`. An optional hint overrides the choice, and `--explain` shows it.
106
+ - The rules about which kind may hold which go away (today a record can't embed a struct, and a struct field can't be an enum). Traits with fields embed structs.
107
+ - Result: `struct` for products, `enum` for sums, `trait` for shared behaviour, essentially Gleam's model with Zig's names.
108
+ - **Order:** after FBIP.
109
+
100
110
  ## 10. Next after that: deterministic games
101
111
 
102
112
  - **Discussion:** pure updates make `step(state, input)` repeatable, but full determinism also needs a fixed timestep, a seeded random generator kept in game state, and recorded inputs. Plum's `Math.sin`/`cos` are written in Plum, and wasm `f64` gives the same results in every engine.