From b45a1edae034e026697e0785722111bf343ee936 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Wed, 16 Sep 2026 10:43:25 +0200 Subject: [PATCH] Cut the comments that restate the README or narrate the arrangement, and name the record fence asymmetry in Decisions --- README.md | 4 +++- draw.go | 3 +-- graph.go | 3 --- perf_test.go | 7 ++----- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index da3d8fa..3a11981 100644 --- a/README.md +++ b/README.md @@ -709,7 +709,9 @@ tokens add cost in proportion to the output. category, which both reference. That settled, a record's column fences run at `New` too, so a category that loads renders as whichever shape is asked for, and a reference reaching back into a category through another one is refused there as the overlap it - is. + is. Which reads those fences weigh differs on purpose: a record-only template's inert + format renders nothing, so a `drawGroup` on it can never matter and is refused, while + one on a rendering format can matter to a caller that bare-references it. - **A record's column set is fixed before the first draw.** Only a category-level template is a record: a path descending into a field, or naming a folder or a choice, errors. A tail may pass through a choice whose variants carry different diff --git a/draw.go b/draw.go index e7c466f..ba2d061 100644 --- a/draw.go +++ b/draw.go @@ -154,8 +154,7 @@ func (c *drawCheck) checkRecordDraws(path string, n node) error { if !ok || !t.record { return nil } - // A record's columns are its fields, which its format need not render at all, so the - // reads to weigh are theirs rather than the template's own. + // A record-only template's format renders nothing, so weigh the columns, not the format. columns := recordColumns(t) reads := false for _, name := range columns { diff --git a/graph.go b/graph.go index b1dd371..66a03e6 100644 --- a/graph.go +++ b/graph.go @@ -197,9 +197,6 @@ func checkRenders(s nodeScope) error { return err } fence := &drawCheck{} - // One pass refuses a draw group that splits nothing and notes whether the scope binds a - // reference at all: weighing what a render's draws hold walks every node it renders, and - // with nothing bound there is no draw to share, so the shipped set pays for neither walk. refs := false if err := s(func(path string, n node) error { if t, ok := n.(*template); ok && len(t.refs) > 0 { diff --git a/perf_test.go b/perf_test.go index 4ff2bbf..75d1e86 100644 --- a/perf_test.go +++ b/perf_test.go @@ -51,11 +51,7 @@ func TestNoRenderAllocRegression(t *testing.T) { } } -// A record's fences read the compiled tree, so they belong to New, not to a draw. -// A reference path read across a repeat, and one read in a named draw group. The repeat -// prices both measures that keep a render's draw set off the heap — inlining expandAnew -// into render's loop, or keying a draw group's map with the scope's own string, costs an -// allocation an iteration — while the draw group holds the group path's own count. +// The repeat shape prices both escape measures: dropping either costs an alloc an iteration. func TestNoReferenceAllocRegression(t *testing.T) { word := `{"format":"{w}","w":["alpha","beta","gamma","delta"]}` for _, s := range []struct { @@ -78,6 +74,7 @@ func TestNoReferenceAllocRegression(t *testing.T) { } } +// A record's fences read the compiled tree, so they belong to New, not to a draw. func TestNoRecordAllocRegression(t *testing.T) { for _, s := range []struct{ name, json string }{ {"record 3 columns", `{"format":"","a":"x","b":"y","c":"z"}`},