plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
784decf
— Peter John
2026-11-04T20:45:59+05:30
docs: run A plan split
docs/plans/2026-11-04-language-simplification-a.md
CHANGED
|
@@ -17,69 +17,112 @@
|
|
|
17
17
|
## Task graph
|
|
18
18
|
```mermaid
|
|
19
19
|
flowchart LR
|
|
20
|
-
T1[list literal]
|
|
20
|
+
T1[list literal grammar]
|
|
21
|
+
T8[list literal desugar]
|
|
21
22
|
T2[std off variadics]
|
|
23
|
+
T9[rust tests off variadics]
|
|
22
24
|
T3[Seq step struct]
|
|
25
|
+
T10[for over next]
|
|
23
26
|
T4[std off generators]
|
|
24
27
|
T5[errors and = inventory]
|
|
28
|
+
T6[remove syntax]
|
|
25
|
-
|
|
29
|
+
T11[remove checker codegen]
|
|
26
30
|
T7[verify run A]
|
|
27
31
|
%% taskgraph
|
|
28
|
-
T1 -->
|
|
32
|
+
T1 --> T8
|
|
33
|
+
T8 --> T2
|
|
34
|
+
T8 --> T9
|
|
29
|
-
|
|
35
|
+
T8 --> T3
|
|
36
|
+
T3 --> T10
|
|
37
|
+
T10 --> T4
|
|
30
|
-
|
|
38
|
+
T2 --> T4
|
|
31
|
-
T2 --> T6
|
|
32
39
|
T4 --> T6
|
|
40
|
+
T9 --> T6
|
|
33
41
|
T5 --> T6
|
|
34
|
-
T6 -->
|
|
42
|
+
T6 --> T11
|
|
43
|
+
T11 --> T7
|
|
35
44
|
```
|
|
36
|
-
Ruling: sequential - std must stop using a feature before the compiler drops it - cost: longer chain.
|
|
45
|
+
Ruling: sequential - std must stop using a feature before the compiler drops it, and List/Map/grammar files are edited in turn - cost: longer chain.
|
|
37
46
|
|
|
38
47
|
## Package A: new forms
|
|
39
48
|
**Probe entry:** run=plum test plum-std plum-examples
|
|
40
49
|
|
|
41
|
-
### T1 list literal · Complexity
|
|
42
|
-
**Owns:** plum-tooling/tree-sitter-plum/grammar.js, plum-tooling/tree-sitter-plum/src/**, plum-tooling/tree-sitter-plum/test/corpus/**
|
|
43
|
-
**Components:**
|
|
44
|
-
**LOC owned:**
|
|
50
|
+
### T1 list literal grammar · Complexity 4 · Est. context 40k
|
|
51
|
+
**Owns:** plum-tooling/tree-sitter-plum/grammar.js, plum-tooling/tree-sitter-plum/src/**, plum-tooling/tree-sitter-plum/test/corpus/**
|
|
52
|
+
**Components:** 1
|
|
53
|
+
**LOC owned:** 40
|
|
54
|
+
**Tests:** fast
|
|
55
|
+
**Model:** sonnet
|
|
56
|
+
**Produces:** grammar node `list_literal` = `[` commaSep(expression) `]` at expression start (pairs `k => v` allowed as elements)
|
|
57
|
+
e.g. `xs := [1, 2, 3]` -> (list_literal (int) (int) (int))
|
|
58
|
+
e.g. `["a" => 1]` -> (list_literal (pair_arg ...))
|
|
59
|
+
**Test code:** corpus cases for the e.g. lines and `[]`; existing corpus green (generics `List[Int]` unaffected).
|
|
60
|
+
|
|
61
|
+
### T8 list literal desugar · Complexity 4 · Est. context 45k
|
|
62
|
+
**Owns:** plum-core/src/parser.rs, plum-std/List.plum, plum-std/Map.plum, plum-core/tests/list_literal_test.rs, plum-examples/list_literal_probe.plum
|
|
63
|
+
**Components:** 1
|
|
64
|
+
**LOC owned:** 90
|
|
45
65
|
**Tests:** slow
|
|
46
|
-
**Model:**
|
|
66
|
+
**Model:** sonnet
|
|
47
|
-
**
|
|
67
|
+
**Consumes:** grammar node `list_literal` = `[` commaSep(expression) `]` at expression start (pairs `k => v` allowed as elements) (T1)
|
|
48
|
-
|
|
68
|
+
**Produces:** `[a, b]` parses as `List.empty().append(a).append(b)`; `[k => v]` as `Map.empty().set(k, v)`
|
|
69
|
+
e.g. `xs := [1, 2, 3]` -> List[Int] of 3
|
|
49
70
|
e.g. `xs: List[Int] := []` -> `List.empty()`
|
|
50
|
-
|
|
51
|
-
**Test code:** parser tests asserting the desugared AST for the three e.g. lines; a `.plum` test block in the probe file checking length/get of each; grammar corpus green. List and Map get `empty()` / `append` / `set` if missing (in plum-std/List.plum and Map.plum — ruling: T1 may add those methods only).
|
|
71
|
+
**Test code:** parser tests asserting the desugared AST; probe `.plum` test blocks checking length/get; List/Map gain `empty`/`append`/`set` if missing.
|
|
52
72
|
|
|
53
73
|
## Package B: std and examples
|
|
54
74
|
**Probe entry:** run=plum test plum-std plum-examples
|
|
55
75
|
|
|
56
|
-
### T2 std off variadics · Complexity
|
|
57
|
-
**Owns:** plum-std/List.plum, plum-std/Map.plum, plum-std/Json.plum, plum-std/Slice.plum, plum-examples/basics.plum, plum-examples/structs_records.plum
|
|
76
|
+
### T2 std off variadics · Complexity 3 · Est. context 40k
|
|
77
|
+
**Owns:** plum-std/List.plum, plum-std/Map.plum, plum-std/Json.plum, plum-std/Slice.plum, plum-examples/basics.plum, plum-examples/structs_records.plum
|
|
58
78
|
**Components:** 1
|
|
59
|
-
**LOC owned:**
|
|
79
|
+
**LOC owned:** 60
|
|
60
80
|
**Tests:** slow
|
|
81
|
+
**Model:** sonnet
|
|
61
|
-
**Consumes:**
|
|
82
|
+
**Consumes:** `[a, b]` parses as `List.empty().append(a).append(b)`; `[k => v]` as `Map.empty().set(k, v)` (T8)
|
|
62
83
|
**Produces:** none
|
|
63
|
-
**Test code:**
|
|
84
|
+
**Test code:** `List.init`/`Map.init` deleted; other `...T` params take `List[T]`; `List(1, 2, 3)`/`Map("a" => 1)` become `[1, 2, 3]`/`["a" => 1]`; gates pass.
|
|
64
85
|
|
|
86
|
+
### T9 rust tests off variadics · Complexity 3 · Est. context 40k
|
|
87
|
+
**Owns:** plum-wasm-codegen/tests/**, plum-checker/tests/**, plum-core/tests/** except list_literal_test.rs
|
|
88
|
+
**Components:** 1
|
|
89
|
+
**LOC owned:** 60
|
|
90
|
+
**Tests:** slow
|
|
91
|
+
**Model:** sonnet
|
|
92
|
+
**Consumes:** `[a, b]` parses as `List.empty().append(a).append(b)`; `[k => v]` as `Map.empty().set(k, v)` (T8)
|
|
93
|
+
**Produces:** none
|
|
94
|
+
**Test code:** embedded Plum sources in Rust tests use `[..]` instead of `List(..)`/`Map(..)` and no `...T`; same test counts.
|
|
95
|
+
|
|
65
|
-
### T3 Seq as a step struct · Complexity
|
|
96
|
+
### T3 Seq as a step struct · Complexity 4 · Est. context 45k
|
|
66
|
-
**Owns:** plum-std/Seq.plum
|
|
97
|
+
**Owns:** plum-std/Seq.plum
|
|
67
|
-
**Components:**
|
|
98
|
+
**Components:** 1
|
|
99
|
+
**LOC owned:** 95
|
|
100
|
+
**Tests:** slow
|
|
101
|
+
**Model:** sonnet
|
|
102
|
+
**Consumes:** `[a, b]` parses as `List.empty().append(a).append(b)`; `[k => v]` as `Map.empty().set(k, v)` (T8)
|
|
103
|
+
**Produces:** std Seq[T] { next: fn() -> T? } with range/map/filter/take/fold as plain fns
|
|
104
|
+
e.g. `Seq.range(0, 10).filter(|n| n % 2 == 0).take(2).fold(0, |a, n| a + n)` -> 2
|
|
105
|
+
**Test code:** Seq.plum test blocks for the e.g. line and every old Seq test rewritten with explicit `next()` loops (no `for x := s` yet).
|
|
106
|
+
|
|
107
|
+
### T10 for over next · Complexity 4 · Est. context 45k
|
|
108
|
+
**Owns:** plum-core/src/forms.rs, plum-checker/src/lib.rs, plum-wasm-codegen/src/lib.rs, plum-core/tests/for_next_test.rs
|
|
109
|
+
**Components:** 1
|
|
68
|
-
**LOC owned:**
|
|
110
|
+
**LOC owned:** 80
|
|
69
111
|
**Tests:** slow
|
|
70
|
-
**
|
|
112
|
+
**Model:** sonnet
|
|
71
|
-
**
|
|
113
|
+
**Consumes:** std Seq[T] { next: fn() -> T? } with range/map/filter/take/fold as plain fns (T3)
|
|
114
|
+
**Produces:** `for x := s` over any value with `next(self) -> T?`
|
|
72
115
|
e.g. `for x := Seq.range(0, 3)` binds 0, 1, 2
|
|
73
|
-
e.g. `Seq.range(0, 10).filter(|n| n % 2 == 0).take(2)` -> 0, 2
|
|
74
|
-
**Review Focus:** fusion: `fusion_alloc_test` and
|
|
116
|
+
**Review Focus:** fusion: `fusion_alloc_test` and List-chain fusion still pass; report any lost fusion with numbers.
|
|
75
|
-
**Test code:**
|
|
117
|
+
**Test code:** for_next_test for the e.g. line; gates pass.
|
|
76
118
|
|
|
77
119
|
### T4 std and examples off generators · Complexity 4 · Est. context 45k
|
|
78
120
|
**Owns:** plum-std/Map.plum, plum-std/Int.plum, plum-std/List.plum, plum-examples/functional.plum, plum-examples/sequences.plum
|
|
79
121
|
**Components:** 1
|
|
80
122
|
**LOC owned:** 100
|
|
81
123
|
**Tests:** slow
|
|
124
|
+
**Model:** sonnet
|
|
82
|
-
**Consumes:**
|
|
125
|
+
**Consumes:** `for x := s` over any value with `next(self) -> T?` (T10)
|
|
83
126
|
**Produces:** none
|
|
84
127
|
**Test code:** no `fun*`/`yield` left in plum-std or plum-examples; all gates pass.
|
|
85
128
|
|
|
@@ -94,21 +137,32 @@ e.g. `Seq.range(0, 10).filter(|n| n % 2 == 0).take(2)` -> 0, 2
|
|
|
94
137
|
## Package C: remove and verify
|
|
95
138
|
**Probe entry:** run=plum test plum-std plum-examples
|
|
96
139
|
|
|
97
|
-
### T6 remove
|
|
140
|
+
### T6 remove syntax · Complexity 4 · Est. context 45k
|
|
98
|
-
**Owns:** plum-tooling/tree-sitter-plum/**, plum-core/src/
|
|
141
|
+
**Owns:** plum-tooling/tree-sitter-plum/**, plum-core/src/parser.rs, plum-core/src/ast.rs, plum-std/**, plum-examples/**
|
|
99
|
-
**Components:**
|
|
142
|
+
**Components:** 2
|
|
100
|
-
**LOC owned:**
|
|
143
|
+
**LOC owned:** 80
|
|
144
|
+
**Tests:** slow
|
|
145
|
+
**Model:** sonnet
|
|
146
|
+
**Produces:** none
|
|
147
|
+
**Review Focus:** each removed form gives a clear parse/check error naming its replacement (`...T` → `List[T]` + `[..]`; `fun*` → Seq; value enum → plain enum; first-use `=` → `:=`).
|
|
148
|
+
**Test code:** parser tests for each error; gates pass; grep finds none of the removed syntax in std/examples/grammar.
|
|
149
|
+
**Steps:** fix every `=` site from T5's inventory with `:=`; delete grammar rules and AST variants for variadics, `fun*`/`yield`, value-enum discriminants, and the error forms T5 listed.
|
|
150
|
+
|
|
151
|
+
### T11 remove checker and codegen support · Complexity 4 · Est. context 45k
|
|
152
|
+
**Owns:** plum-core/src/*.rs except parser.rs and ast.rs, plum-checker/src/*.rs, plum-wasm-codegen/src/lib.rs, plum-lsp/src/*.rs, plum-*/tests/**
|
|
153
|
+
**Components:** 2
|
|
154
|
+
**LOC owned:** 60
|
|
101
155
|
**Tests:** slow
|
|
156
|
+
**Model:** sonnet
|
|
102
157
|
**Produces:** none
|
|
103
|
-
**
|
|
104
|
-
**Test code:** checker tests for each error message; all gates pass; grep finds none of the removed syntax in std/examples/grammar.
|
|
105
|
-
**Steps:** fix every `=` site from T5's inventory with `:=`; delete grammar rules, AST variants, checker intrinsics (variadic length/at, generator typing, value-enum checks, the `?.`→andThen path, forms already listed in T5), codegen value-enum helpers.
|
|
158
|
+
**Test code:** variadic length/at intrinsics, generator typing and lowering, value-enum checks, the `?.`→andThen path, first-use declaration and codegen value-enum helpers are deleted; checker test for the `=` error message; gates pass.
|
|
106
159
|
|
|
107
160
|
### T7 verify run A · Complexity 2 · Est. context 30k
|
|
108
161
|
**Owns:** docs/plans/2026-11-04-language-simplification-a.results.md
|
|
109
162
|
**Components:** 1
|
|
110
163
|
**LOC owned:** 40
|
|
111
164
|
**Tests:** slow
|
|
165
|
+
**Model:** sonnet
|
|
112
166
|
**Produces:** none
|
|
113
167
|
**Test code:** workspace binaries, plum test, plum-game host_test, browser game check if available; Rust LOC removed per crate vs the start sha.
|
|
114
168
|
|