Say hold where the prose still said draws

This commit is contained in:
2026-09-21 21:54:50 +02:00
committed by Lillem4n
parent a52adc6b0d
commit 41dbbd3fda
10 changed files with 16 additions and 17 deletions
+3 -3
View File
@@ -1080,9 +1080,9 @@ the Development section below, and who ships a register the four above then draw
- **`hold` names what a render keeps, `draw` what it draws.** Goal 2 wants a name to - **`hold` names what a render keeps, `draw` what it draws.** Goal 2 wants a name to
reach one unit: `hold`, `holdSet` and `renderScope` are what a render holds while it reach one unit: `hold`, `holdSet` and `renderScope` are what a render holds while it
renders, and `draw`, `drawGroup` and `drawfence.go`'s units are the draws and the renders, and `draw`, `drawGroup` and `drawfence.go`'s units are the draws and the
load fence over them. So `holdset.go` is fenced by `drawfence.go`, which does not load fence over them, so `holdfence.go` fences the hold an expansion keeps and
pair by name as `hold.go` and `holdfence.go` do: that fence is over reference draws, `drawfence.go` the reference draws `holdset.go` keeps. Valid while the load fences
wherever a render keeps them. Valid while the load fences sit in files of their own. sit in files of their own.
- **A function may not spell a method; two types may.** A call writes a method with - **A function may not spell a method; two types may.** A call writes a method with
its receiver and a function bare, so one name on both greps as one unit, which is its receiver and a function bare, so one name on both greps as one unit, which is
the reaching cost goal 2 counts, while the receiver before a shared method name the reaching cost goal 2 counts, while the receiver before a shared method name
+1 -1
View File
@@ -25,7 +25,7 @@ func newHoldSet(s *session) holdSet {
return holdSet{unnamed: hold{variant: map[string]node{}, value: map[string]draw{}, s: s}} return holdSet{unnamed: hold{variant: map[string]node{}, value: map[string]draw{}, s: s}}
} }
// renderOnce renders n as one render, over draws of its own. // renderOnce renders n as one render, over a hold set of its own.
func renderOnce(s *session, n node) string { func renderOnce(s *session, n node) string {
set := holdSet{unnamed: hold{s: s}} set := holdSet{unnamed: hold{s: s}}
return render(s, n, renderScope{set: &set}) return render(s, n, renderScope{set: &set})
+2 -3
View File
@@ -8,8 +8,6 @@ import (
"testing" "testing"
) )
// TestNoFunctionSpellsAMethod holds a call to one unit, over the tests as well,
// since a test file is this package too.
func TestNoFunctionSpellsAMethod(t *testing.T) { func TestNoFunctionSpellsAMethod(t *testing.T) {
funcs, methods := declaredCalls(namespaceFiles(t)) funcs, methods := declaredCalls(namespaceFiles(t))
names := make([]string, 0, len(funcs)) names := make([]string, 0, len(funcs))
@@ -19,7 +17,8 @@ func TestNoFunctionSpellsAMethod(t *testing.T) {
sort.Strings(names) sort.Strings(names)
for _, name := range names { for _, name := range names {
if recv := methods[name]; len(recv) > 0 { if recv := methods[name]; len(recv) > 0 {
t.Errorf("func %s and %s are two units under one name; name them apart", name, strings.Join(recv, " and ")) sort.Strings(recv)
t.Errorf("func %s is spelled by %s too; name them apart", name, strings.Join(recv, " and "))
} }
} }
} }
+1 -1
View File
@@ -74,7 +74,7 @@ type template struct {
// held is every name drawn once per expansion: the bound levels above, plus the // held is every name drawn once per expansion: the bound levels above, plus the
// siblings a {calc()} reads. nil when the format holds nothing (see expand). // siblings a {calc()} reads. nil when the format holds nothing (see expand).
held map[string]bool held map[string]bool
heldLocal bool // some held name is kept by the expansion itself, so expand makes its draws heldLocal bool // some held name is kept by the expansion itself, so expand makes its hold
// Filled by `linkTemplateRefs` and `keyDrawGroup`, from the assembled tree: // Filled by `linkTemplateRefs` and `keyDrawGroup`, from the assembled tree:
refs map[string]refBinding // each reference the format reads -> what it is bound to refs map[string]refBinding // each reference the format reads -> what it is bound to
+2 -2
View File
@@ -69,12 +69,12 @@ func TestNoReferenceAllocRegression(t *testing.T) {
t.Fatalf("New(%s): %v", s.name, err) t.Fatalf("New(%s): %v", s.name, err)
} }
if allocs := testing.AllocsPerRun(10000, func() { f.Fake("x") }); allocs > s.base*1.10 { if allocs := testing.AllocsPerRun(10000, func() { f.Fake("x") }); allocs > s.base*1.10 {
t.Errorf("%s: %.1f allocs/op regressed past %.1f (baseline %.1f + 10%%); a draw set reaching the heap is the usual cause", s.name, allocs, s.base*1.10, s.base) t.Errorf("%s: %.1f allocs/op regressed past %.1f (baseline %.1f + 10%%); a hold set reaching the heap is the usual cause", s.name, allocs, s.base*1.10, s.base)
} }
} }
} }
// A table read pins a row in the render's draws and reads its cells in place. // A table read pins a row in the render's hold and reads its cells in place.
func TestNoTableAllocRegression(t *testing.T) { func TestNoTableAllocRegression(t *testing.T) {
f, err := New(WithoutShippedData(), WithDataFS(fstest.MapFS{ f, err := New(WithoutShippedData(), WithDataFS(fstest.MapFS{
"region.json": {Data: []byte(`{"format":"{name}","rows":"region.tsv","key":"code","weight":"population"}`)}, "region.json": {Data: []byte(`{"format":"{name}","rows":"region.tsv","key":"code","weight":"population"}`)},
+1 -1
View File
@@ -261,7 +261,7 @@ func recordOf(n node) (*template, []Column, error) {
} }
// renderRecord draws each column once, in the name order recordOf fixed, as one render // renderRecord draws each column once, in the name order recordOf fixed, as one render
// over sc's draws; a table's columns read the row pinned there. // over sc's hold; a table's columns read the row pinned there.
func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record { func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record {
sc = sc.in(t) sc = sc.in(t)
if t.table != nil { if t.table != nil {
+2 -2
View File
@@ -53,7 +53,7 @@ func descend(s *session, root node, segments []string, sc renderScope) (node, er
// render evaluates a compiled node to a string. compile validates every node up // render evaluates a compiled node to a string. compile validates every node up
// front, so rendering a compiled tree cannot fail. sc holds the reference draws the // front, so rendering a compiled tree cannot fail. sc holds the reference draws the
// render shares; each repeat iteration renders over draws of its own. // render shares; each repeat iteration renders over a hold set of its own.
func render(s *session, n node, sc renderScope) string { func render(s *session, n node, sc renderScope) string {
switch n := n.(type) { switch n := n.(type) {
case *choice: case *choice:
@@ -124,7 +124,7 @@ func expand(s *session, t *template, sc renderScope) string {
b.Grow(t.grow) b.Grow(t.grow)
// One draw per held name, for this expansion only: a nested template and each // One draw per held name, for this expansion only: a nested template and each
// repeat iteration get their own, since each is its own expansion. A reference // repeat iteration get their own, since each is its own expansion. A reference
// path reads the render's draws in sc instead. // path reads the render's hold in sc instead.
var held *hold var held *hold
if t.heldLocal { if t.heldLocal {
held = &hold{ held = &hold{
+1 -1
View File
@@ -463,7 +463,7 @@ func (t *table) indexed() *tableIndex {
} }
// draw picks a row over the whole table. The session is concrete rather than the rng // draw picks a row over the whole table. The session is concrete rather than the rng
// interface so that a walk holding the draws allocates nothing. // interface so that a hold carrying it allocates nothing.
func (t *table) draw(s *session) int { func (t *table) draw(s *session) int {
if t.cum == nil { if t.cum == nil {
return s.IntN(t.rows()) return s.IntN(t.rows())
+1 -1
View File
@@ -366,7 +366,7 @@ type formatOps struct {
bound map[string]string bound map[string]string
held map[string]bool held map[string]bool
holder map[string]string holder map[string]string
heldLocal bool // some held name is kept by the expansion itself rather than the render's draws heldLocal bool // some held name is kept by the expansion itself rather than the render's hold
} }
func (c *formatOps) holdName(a arm, label string) { func (c *formatOps) holdName(a arm, label string) {
+2 -2
View File
@@ -16,8 +16,8 @@ scoring run names too little to steer one. A fresh run replaces the items below.
Scores, newest last: 5.9 on 2026-09-20 (Navigation 7.0, Locality 5.2, Shape 5.9, Scores, newest last: 5.9 on 2026-09-20 (Navigation 7.0, Locality 5.2, Shape 5.9,
Self-sufficiency 5.7), eight of nine seats capped by Locality or Self-sufficiency, all Self-sufficiency 5.7), eight of nine seats capped by Locality or Self-sufficiency, all
nine naming `hold.go`, `draw.go` — now `holdset.go` and `drawfence.go` — and nine naming `hold.go`, `draw.go` — now `holdset.go` and `drawfence.go` — and
`family.go` first for reading cost: 1,138 lines in which each file carries both a `family.go` first for reading cost: 1,138 lines in which each file carried both a
load-time fence and render-time machinery, so no file name says whether a unit runs at load-time fence and render-time machinery, so no file name said whether a unit ran at
`New` or at `Fake`. `New` or at `Fake`.
This round, in order: This round, in order: