plum

#treesitter#compiler#wasm

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

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


4640b26 — Peter John 2026-11-04T10:22:57+05:30
docs: update/render component names; std imperative folder task
docs/decisions/2026-11-language-and-scene-decisions.md CHANGED
@@ -11,10 +11,11 @@ A record of the design decisions taken in the 2026-11-03/04 sessions, with the r
11
11
  ## 2. Three scene styles, three folders
12
12
 
13
13
  - **Decision (user):** each style lives in its own folder, because one shared folder was confusing.
14
- - `plum-std/game/`: shared basics (`Game`, `Vec2`, `Color`, `Affine`) and the mutable `Scene`.
14
+ - `plum-std/game/`: shared basics (`Game`, `Vec2`, `Color`, `Affine`).
15
+ - `plum-std/game/imperative/`: the mutable `Scene` (moved 2026-11-04, user).
15
16
  - `plum-std/game/pure/`: PureScene, SceneTree, SceneInput, Actions (pure updates, in place via `own` today).
16
17
  - `plum-std/game/functional/`: Picture, Anim, Ui (state/view).
17
- - `plum-examples/games/pure/` and `plum-examples/games/functional/` for their example games. `plum game` finds assets in the nearest parent `assets/` folder.
18
+ - `plum-examples/games/imperative/`, `games/pure/` and `games/functional/` for their example games (the mutable games moved too, 2026-11-04). PureScene is imperative under an ownership discipline (`act(own n)` edits a retained tree in place); only the functional component style is functional. `plum game` finds assets in the nearest parent `assets/` folder.
18
19
 
19
20
  ## 3. Pure scene on enums
20
21
 
@@ -39,7 +40,7 @@ A record of the design decisions taken in the 2026-11-03/04 sessions, with the r
39
40
  ## 4b. Component style for the functional game (React/Elm model)
40
41
 
41
42
  - **Observation (user):** the pure example read more easily than the functional one, because each kind (Orb, Ship) kept its data, behaviour and drawing together, while the functional file spread an orb over many functions, nested `Cons(head:, tail:)` literals, rebuilt list helpers and threaded random seeds by hand.
42
- - **Decision (user):** keep the cohesion and the purity: per-kind records with `step(self, ..) -> Self` (Elm `update`) and `view(self, ..) -> SceneNode` (a React component returning a tree), a `State` with its own `step`/`view`, `List(...)` literals, an `Rng` value. Heterogeneous kinds can use a trait (`trait Entity = fun step(self, dt) -> Entity; fun view(self, ..) -> SceneNode`). The tree costs nothing at runtime because the supercompiler fuses `Picture.draw(io, state.view())`; nothing is diffed because every frame is redrawn.
43
+ - **Decision (user):** keep the cohesion and the purity: per-kind records with `update(self, ..) -> Self` (Elm's `update`) and `render(self, ..) -> SceneNode` (React's `render()` returning elements; the user chose these names over `step`/`view`), a `State` with its own `update`/`render`, `List(...)` literals, an `Rng` value. Heterogeneous kinds can use a trait (`trait Entity = fun update(self, dt) -> Entity; fun render(self, ..) -> SceneNode`). The tree costs nothing at runtime because the supercompiler fuses `Picture.draw(io, state.render())` (render builds the tree, draw paints it); nothing is diffed because every frame is redrawn.
43
44
  - **Plan:** done in the language-restrictions plan's T14. PureScene stays for now; retiring it (two styles left: mutable `Scene` and functional components) is a follow-up once the result is seen.
44
45
 
45
46
  ## 5. Functional scene graphs: notes from the discussion
docs/plans/2026-11-03-language-restrictions.md CHANGED
@@ -52,6 +52,8 @@ flowchart LR
52
52
  T13[migrate io ex]
53
53
  T14[migrate mut ex]
54
54
  T15[delete own]
55
+ T16[imperative games]
56
+ T17[imperative std]
55
57
  %% taskgraph
56
58
  T1 --> T2
57
59
  T2 --> T3
@@ -67,6 +69,8 @@ flowchart LR
67
69
  T9 --> T10
68
70
  T10 --> T15
69
71
  T15 --> T11
72
+ T16 --> T17
73
+ T17 --> T6
70
74
  ```
71
75
 
72
76
  Ruling: sequential [chain-lr] - T1 T2 T4 T5 T7 T9 T10 all change plum-checker/src/lib.rs and/or plum-core passes, and each migration task compiles against the previous rule; one shared checkout - cost if wrong: ~30 min longer wall clock.
@@ -158,7 +162,7 @@ e.g. `fun view(s: State) -> SceneNode = ...` -> pure; `fun render(io: Io, n: Sce
158
162
  **Test code:** the e.g. cases; fusion_alloc_test green.
159
163
 
160
164
  ### T6 migrate std to `io` · Complexity 4 (O-1) · Est. context 50k
161
- **Owns:** plum-std/game/functional/Picture.plum, plum-std/game/Scene.plum, plum-std/game/pure/PureScene.plum, plum-std/game/pure/SceneTree.plum, plum-std/game/pure/SceneInput.plum, plum-std/Testing.plum
165
+ **Owns:** plum-std/game/functional/Picture.plum, plum-std/game/imperative/Scene.plum, plum-std/game/pure/PureScene.plum, plum-std/game/pure/SceneTree.plum, plum-std/game/pure/SceneInput.plum, plum-std/Testing.plum
162
166
  **Components:** 1
163
167
  **LOC owned:** 110
164
168
  **Tests:** fast
@@ -218,7 +222,7 @@ Package: compiler + std; categories: state, deep.
218
222
  **Model:** sonnet
219
223
  **Est. time:** 5 min
220
224
  **Consumes:** none
221
- **Produces:** examples/games/fixtures: game shells' changing fields (World.state etc.) `mut`, pure game code on spreads; `--allow-mutation` removed from the checker/CLI; games/functional/game_state_view.plum rewritten in the component style (user, 2026-11-04): per-kind records (Ship, Orb, Mine, Star) with `step(self, ..) -> Self` and `view(self, ..) -> SceneNode`, a `State` with `step`/`view`, `List(...)` and std List methods instead of Cons chains and the homemade list helpers, an `Rng` value instead of hand-threaded seeds and helper records, the draw path `Picture.draw(io, w.state.view())` still fully fused (fusion_alloc_test green); game tests keep names and values
225
+ **Produces:** examples/games/fixtures: game shells' changing fields (World.state etc.) `mut`, pure game code on spreads; `--allow-mutation` removed from the checker/CLI; games/functional/game_state_view.plum rewritten in the component style (user, 2026-11-04): per-kind records (Ship, Orb, Mine, Star) with `update(self, ..) -> Self` and `render(self, ..) -> SceneNode`, a `State` with `update`/`render`, `List(...)` and std List methods instead of Cons chains and the homemade list helpers, an `Rng` value instead of hand-threaded seeds and helper records, the draw path `Picture.draw(io, w.state.render())` still fully fused (fusion_alloc_test green); game tests keep names and values
222
226
  **Review Focus:** state: game behaviour identical (host parity, browser checks).
223
227
  **Test code:** full suite green; host_test + web_check green.
224
228
 
@@ -270,6 +274,30 @@ Package: compiler + std; categories: state, deep.
270
274
  **Review Focus:** numeric: no unexplained regression.
271
275
  **Test code:** README snippets parse (plum-lsp test readmeSnippetsHaveNoSyntaxDiagnostics); benchmark table.
272
276
 
277
+ ### T16 imperative games folder (user, 2026-11-04) · Complexity 2 (O-1) · Est. context 30k
278
+ **Owns:** plum-examples/game.plum, plum-examples/game_scene.plum, plum-examples/scene.plum, plum-examples/games/imperative, plum-game/tests/host_test.rs, plum-game/web-test/tests/web_check.rs, plum-game/web-test/BENCHMARK.md, README.md
279
+ **Components:** 1
280
+ **LOC owned:** 40
281
+ **Tests:** slow
282
+ **Model:** sonnet
283
+ **Est. time:** 3 min
284
+ **Consumes:** none
285
+ **Produces:** `git mv` game.plum, game_scene.plum, scene.plum to plum-examples/games/imperative/; every reference updated (host tests, web checks, BENCHMARK.md, README, any Rust test loading them by path); traits.plum / trait_scene.plum stay at the top level
286
+ **Review Focus:** protocol: assets still resolve (nearest parent assets/), host + browser checks green.
287
+ **Test code:** `run_tests --fast plum-game/tests/host_test.rs plum-game/web-test/tests/web_check.rs plum-examples` green.
288
+
289
+ ### T17 std imperative folder (user, 2026-11-04) · Complexity 2 (O-1) · Est. context 30k
290
+ **Owns:** plum-std/game/imperative/Scene.plum, plum-std/game/Scene.plum, plum-examples/games/imperative, plum-examples/traits.plum, plum-examples/trait_scene.plum, plum-game/web-test/fixtures/stress_scene.plum, plum-game/web-test/fixtures/stress_world.plum, README.md
291
+ **Components:** 1
292
+ **LOC owned:** 30
293
+ **Tests:** slow
294
+ **Model:** sonnet
295
+ **Est. time:** 3 min
296
+ **Consumes:** none
297
+ **Produces:** `git mv plum-std/game/Scene.plum plum-std/game/imperative/Scene.plum`; every `import std/game/Scene` becomes `import std/game/imperative/Scene`
298
+ **Review Focus:** protocol: host + browser checks green.
299
+ **Test code:** run_tests --fast plum-std, plum-examples, plum-game/tests/host_test.rs, plum-game/web-test/tests/web_check.rs green.
300
+
273
301
  ## Review Focus
274
302
  Per package lines above.
275
303