Make goal 4 ask for intuitive templates, and decide a selected row is fixed, not drawn
This commit is contained in:
@@ -71,7 +71,7 @@ In [docs/decisions.md](docs/decisions.md):
|
||||
- A selector is bracketed, and a dot inside it is literal
|
||||
- `parent` names the link column and the table alike
|
||||
- After a row, a path names a column or a linked table
|
||||
- Every reference path into one family selects the same rows, per render and group
|
||||
- A selected row is fixed, not drawn, and an unnamed read beside it is refused
|
||||
- A parent row with no child row is a load error
|
||||
- The choice-of-rows fence guards a data file's root, and requires string fields
|
||||
- A table is a record of string columns
|
||||
|
||||
@@ -823,9 +823,12 @@ the Development section below, and who ships a register the four above then draw
|
||||
3. **Valid by construction** — every value passes the check its real consumer
|
||||
applies; facts that belong together come from one draw, within a value and
|
||||
across categories.
|
||||
4. **Text means what it says** — a format renders as written; only `{…}` varies,
|
||||
random characters included (`{digits(3)}`). One spelling per result; the wrong
|
||||
one is a load error naming the right one.
|
||||
4. **Templates are intuitive, and text means what it says** — a template does what
|
||||
its writer expects on first reading. A format renders as written; only `{…}`
|
||||
varies, random characters included (`{digits(3)}`), and a selected row, `[SE]`,
|
||||
is that row wherever it is written. Where a reader could expect two outputs, the
|
||||
template is a load error naming a spelling for each. One spelling per result; the
|
||||
wrong one is a load error naming the right one.
|
||||
5. **Every mistake is a load error** — `New` rejects the data and `NewTemplate`
|
||||
the inline template; on a loaded generator `Fake` fails only for an unknown
|
||||
path, `FakeStruct` only for a non-struct argument or a type its tags do not
|
||||
|
||||
+16
-9
@@ -359,14 +359,22 @@ folder or another column name would be asking for a second spelling.
|
||||
today; admitting it later is additive, since a refused spelling gains a meaning and no
|
||||
accepted one changes, so the door stays open for the address records the plan describes.
|
||||
|
||||
## Every reference path into one family selects the same rows, per render and group
|
||||
## A selected row is fixed, not drawn, and an unnamed read beside it is refused
|
||||
|
||||
A selector pins rows for the render, and a read that draws freely before it could pin a
|
||||
row the selector contradicts, so accepting both would make the result depend on which
|
||||
token rendered first. Requiring one selection per family per group is checkable at load
|
||||
with no data lookup beyond the selectors themselves, and the error names the rewrite.
|
||||
Two selectors naming one row by key and by name compare equal, since the load check
|
||||
resolves them.
|
||||
Decided 2026-09-27 by the maintainer, for goal 4; valid while a selector names exactly one row.
|
||||
|
||||
- Selected rows never conflict: `{/misc.territory[SE].capital} / {/misc.territory[FI].capital}`
|
||||
renders `Stockholm / Helsinki`, and so may two items of one choice.
|
||||
- What a path draws beneath a selected row is one draw per selection, shared by every
|
||||
path through it: `{/geo.SE.region[12].locality.name}` twice names one locality.
|
||||
- A read naming no row of a table whose family a selection in the render and group
|
||||
names is refused, naming the selected path and a `drawGroup`: beside
|
||||
`{/misc.territory[SE].capital}`, a writer reading `{/misc.territory.currency}` expects
|
||||
`SEK`, and `Stockholm pays in EUR` would pass review. It stays refused beside two
|
||||
selections, since adding `[FI]` to that template would otherwise make it load.
|
||||
|
||||
Checked against three simulated template writers from the Audience, who agreed on each
|
||||
case but the last, where two expected a render and all three accepted the refusal.
|
||||
|
||||
## A parent row with no child row is a load error
|
||||
|
||||
@@ -409,8 +417,7 @@ row, and whatever they reach, do meet, and so does the format beside them. Two r
|
||||
meet unless they sit under different rows of one pinned table; pinning a row pins its
|
||||
ancestors too, so rows under different parents are alternatives as well. A table read
|
||||
whole draws its row apart from every pin, so the rows of one whole read are
|
||||
alternatives only to each other. A choice's items are not alternatives: two items
|
||||
selecting different rows of one family are refused.
|
||||
alternatives only to each other.
|
||||
|
||||
## A table never reaches its own family, by any route
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ func (r *tableRead) selected(t *table) (tableSel, bool) {
|
||||
// read one consistent draw: a table rendered whole beside a path into the family,
|
||||
// a table one read draws that another pins, and two reads pinning different rows.
|
||||
// The reads come sorted by group and path, so which pair is reported does not vary.
|
||||
// docs/decisions.md#every-reference-path-into-one-family-selects-the-same-rows-per-render-and-group
|
||||
func checkFamilies(reads []pathRead) error {
|
||||
for i, r := range reads {
|
||||
if r.tr == nil {
|
||||
|
||||
@@ -47,11 +47,9 @@ This round, in order:
|
||||
where `NewTemplate` and `NewRecordTemplate` do not, and `List` claims to be every
|
||||
path `Fake` accepts, which a selector is too. Delete the dead `table.descends` and
|
||||
the redundant `string(key)` in `checkNoRepeatedItem`.
|
||||
- Keep only the standing choice in the decision "The rows of a table are alternatives",
|
||||
a choice's items refused as alternatives, and give it the goal it serves: the rest
|
||||
defines `alternatives`, which its comment in `family.go` already does, and the README's
|
||||
"which pairs are weighed against each other" sends a reader to the log for that
|
||||
definition.
|
||||
- Delete the decision "The rows of a table are alternatives": it defines `alternatives`,
|
||||
which its comment in `family.go` already does, and the README's "which pairs are
|
||||
weighed against each other" sends a reader to the log for that definition.
|
||||
- Run the nine-seat panel again and file what it names here.
|
||||
|
||||
### Data
|
||||
@@ -59,6 +57,8 @@ This round, in order:
|
||||
Shape: T = table, t = template, c = choice. Read every factual list from a register
|
||||
by a `data-import/` script, as README goal 12 asks.
|
||||
|
||||
- Strip the whitespace `data-import/territory.py` copies from its register:
|
||||
`misc.territory[CW].capital` renders ` Willemstad`, with a leading space.
|
||||
- Place xlsx cells by their `r` reference in `data-import/xlsx.py`: a sheet omitting an
|
||||
empty cell shifts every later column left.
|
||||
- Spell `misc.creditcard`'s digit runs `{digits(n)}`, and refuse a repeat over a lone
|
||||
@@ -171,6 +171,13 @@ by a `data-import/` script, as README goal 12 asks.
|
||||
|
||||
### Library and CLI
|
||||
|
||||
- Render selected rows as the decision "A selected row is fixed, not drawn, and an
|
||||
unnamed read beside it is refused" states: `New` refuses
|
||||
`{/misc.territory[SE].capital} / {/misc.territory[FI].capital}` today, and a choice
|
||||
whose items select different rows. Have the refusal of an unnamed read name a
|
||||
selected path that loads: beside `{/geo.SE.locality[Lund].name}`,
|
||||
`{/geo.SE.municipality.name}` names none today, and the one that holds selects from
|
||||
the top, `{/geo.SE.municipality[Lund].name}`.
|
||||
- Report the same error every load for a table with two bad options, and for a
|
||||
folder with two unnamed rows files: `readTableOptions` and `loadDir` return on the
|
||||
first in Go's map order.
|
||||
@@ -192,9 +199,6 @@ by a `data-import/` script, as README goal 12 asks.
|
||||
error names the category and the two columns but no row, so the author greps a
|
||||
register-sized file for the cell — and "name the fields you want instead" rewrites a
|
||||
cell that is not the one to fix.
|
||||
- Have the family fence offer only a rewrite that works: where the drawn table's rows select
|
||||
more than one row of the family, every `write {/terr[NO].name}` it offers fails the same
|
||||
way, so only the `drawGroup` it also names is left.
|
||||
- Spell a table one way across the family errors: `checkFamilyPair` names
|
||||
`drawn.category`, `pinRow` names `t.path` and `mustRow` panics with `t.category`, so one
|
||||
table is `territory` and `misc.territory`, and the short spelling names no file where two
|
||||
@@ -214,6 +218,10 @@ by a `data-import/` script, as README goal 12 asks.
|
||||
|
||||
### Open questions to settle
|
||||
|
||||
- Decide whether a path steps from a row up to its parent, so
|
||||
`{/geo.SE.locality[Lund].municipality.name}` reads Lund's municipality: three simulated
|
||||
template writers all expected it to, per goal 4, and today it fails with "municipality
|
||||
is a column, and a cell holds no fields". Adding it only accepts a refused spelling.
|
||||
- Decide whether a goal 5 violation joins the comprehension gate's exception list: the
|
||||
`{/sel}|{/sel}` panic waits behind the whole round at 5.9, and
|
||||
`{/geo.SE.locality}|{/geo.SE.municipality}` mispairs the shipped data meanwhile, though a
|
||||
|
||||
Reference in New Issue
Block a user