Repository navigation
mat_lits compares a word match's default with its replay node by node, up to where they meet, not as two JSON strings - #1387
Conversation
7da6de6 to
e516a63
Compare
…d too bendlang#1385 brought main's comp.ts to 63,975 ttok, which put this branch at 64,015. These rewrites take 30 back, with the same output: the File, Scope, Seg and Spine types list several fields per line; term_const, fun_of and intr_of read lit_call's result, h and tld.i as truthiness, since each is an object or an array when present. The branch is at 63,985, and merged with bendlang#1387 (which takes its own share) at 63,989.
|
Thanks @Lorenzobattistela! Added a5ac12d on top of your rebase: 38 more ttok of rewrites of the same kinds, same output.
|
|
Thanks @Iann29! The mat_lits change (comparing node by node instead of as two JSON strings) is a good fix, but we can't merge the trimming commits (e516a63 and a5ac12d) as they are. They save tokens by writing comp.ts in a style the rest of the repo doesn't use. bend.ts is our reference for style, and these commits move away from it:
Behavior is the same, so this is only about style. Where things stand: main is now at 63,848 ttok after #1395. Your mat_lits commit (2583108) alone still applies cleanly and brings comp.ts to 64,112, so it needs about 112 tokens of room. Could you drop the two trimming commits, rebase onto current main, and find that room with real simplifications (dead code, duplicated logic, helpers that can be shared) instead of compressing code? If both this PR and #1386 go in, together they need about 430 tokens, so this is worth planning across both PRs. We're also discussing whether to raise the token cap, so if you prefer, you can wait for that decision before doing the cuts. We'll review once the gate passes. |
…, not as two JSON strings At each single-arm level of a U32 match's bit tree, mat_lits compared JSON.stringify(term_lower(.)) of the level's default and of the covering default replayed. On the AMAGE Eco demo that was 8.1 s of 17.9 s of C emission. The two sides are nearly always equal and share most nodes as the same objects, so same walks both as term_lower would (a lambda opened with one variable at its depth, applications, constructors and matches field by field), stops at the first shared object or difference, and compares any other node by the old key at its depth: the key comparison's answer, without printing the rest of the match.
…fault that differs from its replay only in a constructor or a nested match's arm
a5ac12d to
0fac6eb
Compare
…ts did c36d181 compared a default arm with its parent's by lowering both to JSON, which on nested word matches lowers each level's whole subtree: pong emitted in 1.6-2x main's time, the ray tracer 1.2-1.5x. term_same is now main's walk (bendlang#1387): equal by identity, else node by node, by key only where it does not open. Byte-identical; pong and the ray tracer back to main's emit time or under. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
At every single-arm level of a U32 match's 32-level bit tree,
mat_litsdecides whether the level's default is the covering default replayed. It did this by comparingJSON.stringify(term_lower(·))of both sides, which lowers and prints the rest of the match twice per level. In a multi-column match with literals inside constructor patterns, the rest of the match is large. On the AMAGE Eco demo (amage-si; 1,253 live defs, 7.7 MB of C),mat_litstook 8.1 s of the 17.9 s of C emission.The two sides are nearly always equal, and they share most of their nodes as the same objects.
samewalks both the wayterm_lowerwould: λs opened with the same variable at the same depth, then applications, constructors and matches field by field. It returns true at the first shared object and false at the first difference. Any other node it compares by the old key, lowered at its depth. So it gives the key comparison's answer without printing the rest of the match.Speed
bend lits.bend -o lits.cwith the generator below. Apple M4 Pro, Bun 1.4.0, medians of 5 interleaved runs:step, 8 armsstep, 16 armsstep, 32 armsThe repository's own programs have no match of this shape. Their perf gate results are unchanged (124 / 124).
Same output
.bendfiles undertests/,demos/andbench/, main and this branch give the same exit status, stdout and stderr. Every emitted.c(803) and.js(833) is byte-identical. The generator's C is byte-identical at 8, 16 and 32 arms.mat_litsmade while compiling all of the above was done both ways, with any disagreement logged. That covered 205,970 comparisons (201,496 equal, 4,474 not), andsameagreed with the key on all of them.tests/compile/word_match_cover_fields.bendhas an odd arm and a default that differ only in a constructor, or only in a nested match's last arm. Before this, asamethat skipped constructor names or a match's rest would pass every test.Gates
comp.tsis at 63,968 ttok (cap 64,000). Results: repo 54 / 54, test 1624 / 1624, perf 124 / 124, ping 58 / 58. Not run: CUDA, Linux, Windows.Found while building AMAGE Eco, a UI toolkit written in Bend 2.