Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33

Open
lilleman wants to merge 966 commits from worktree-todo-relative-dates-exact-counts into main
3 changed files with 7 additions and 11 deletions
Showing only changes of commit a1852076fe - Show all commits
+6 -7
View File
@@ -244,13 +244,12 @@ carry both rules and both scopes anyway, and tell them apart at every step.
## A hold set makes its draw maps on the first read
Every render starts from the zero `holdSet`, per goal 2's one spelling. Making the maps
where the set is declared kept a record's on its frame's stack, but a `Fake`'s set lives
on the `Generator`, so there it cost every render two heap allocations and about half the
cheapest one's time, measured 2026-09-28. Lazily, a render reading a reference path pays
those two allocations, a record or struct included, and one reading none pays nothing;
goal 11 holds either way. The allocation gate over a repeat of a reference path and over
a named draw group prices that, and pins what keeps a hold set off the heap.
Every render and every draw group starts from an empty hold, since goal 2 prices a reader
meeting two spellings of one empty set. Making the maps where the set is declared kept a
record's on its frame's stack, but a `Fake`'s set lives on the `Generator`, so there it
cost the cheapest render two heap allocations and 240→390 ns, measured 2026-09-28.
Lazily, a render reading a reference path pays those two allocations, a record or struct
included, and one reading none pays nothing; goal 11 holds either way.
## A category never references itself, and a record's fences run at load
+1 -1
View File
@@ -63,7 +63,7 @@ func (sc renderScope) hold() *hold {
if sc.set.named == nil {
sc.set.named = map[string]*hold{}
}
d = &hold{variant: map[string]node{}, value: map[string]readValue{}}
d = &hold{}
sc.set.named[strings.Clone(sc.group)] = d
}
return d
-3
View File
@@ -300,9 +300,6 @@ because pairing a street with its exact postnummer rewrites shipped rows.
flag, an exit code, an exported name, a fence, a builtin and the lowest Go.
- Measure the allocation gate over the shipped `geo` trees too: `pinSet.inline [8]` is sized
for them, and `perf_test.go` checks a synthetic five-deep tree only.
- Make a named draw group's hold lazy, `&hold{}` in `renderScope.hold`: it escapes
to the heap anyway, so its two eager maps buy no stack and cost two allocations per
group that may never read through them. Check it against the alloc tests.
- Name goal 2's four criteria with the axes the panel scores, so a recorded score maps
back to the clause it came from: the goal spells them out in prose while `todo.md`
records `Navigation`, `Locality`, `Shape` and `Self-sufficiency`.