astero.tables¶
Operation-by-type matrices, which no grammar derives.
astero.tables ¶
Families: the tables a grammar cannot derive, declared once.
astero.grammar handles structure the grammar determines. This handles the
other kind. Which runtime symbol implements list-append for Str is a fact
about the runtime, so nothing derives it and it has to be authored.
What goes wrong is not that it is authored. It is that a family of related
operations gets written as N separate dictionaries, each repeating the index,
each free to disagree about the shared rules, and each with its own way of
saying "this combination does not exist". A Family is one declaration:
LIST = Family.parse(
"list",
normalize={"Bool": "Int64"},
matrix='''
Int64 Float64 Str
append LIST_APPEND_I64 LIST_APPEND_F64 LIST_APPEND_STR
get LIST_GET_I64 LIST_GET_F64 LIST_GET_STR
get_unchecked LIST_GET_I64_U LIST_GET_F64_U .
''',
)
Three things follow. The normalization is stated once and applies to every row,
so a rule like "a Bool crosses as an Int64" cannot be spelled one way here and
another way there. A hole is written as a hole, rather than as a missing key
plus a .get() that returns None. And totality is checkable: every row covers
the index, or says explicitly where it does not.
TableError ¶
Bases: ValueError
A family that does not describe a rectangle.
Family
dataclass
¶
A set of operations over one index, with one normalization.