Conversation
…ts groups as the file does Every public name in math_spec.program follows the naming rule in docs/contributing.md, and a relation and a named expression are read from the program the way the file declares them. Redone on the #569 stack rather than replayed: #494 renamed Walk to Direction and #559 split Partition out of it, so the records this touches no longer exist under the names the original branch changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKUDdoyCtxHXm5Gcuze24W
Documentation build overview
31 files changed ·
|
The stack merged main up through itself while this branch was building. `test_parser.py` gained two records built with the old signatures, so the relation declaration drops its name there and the direction and the partition carry it, which is what those two cases now assert prints. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKUDdoyCtxHXm5Gcuze24W
… does, and a footprint holds kinds `Direction.is_function_read` is `is_single_valued`, which is the phrase the refusal beside it already prints; "function" read as callable. `Footprint.nodes` is `kinds`, because it holds classes and the reading page iterates them as `kind`. Neither is a name lpspec reads. `RelationDeclaration.dim` reads a mapping built once rather than rebuilding `dict(self.columns)` per call, which the typesetter makes once per role inside comprehensions over roles. The naming section of the contributing page said a node names the coordinate map, which describes one node of five and made `Translate` read as a counter-example to its own rule. It now says a node names the operation, with the five verbs and nodes beside each other. docs/contributing.md: n 38, avg 8.7, median 6, over25 2. Both long sentences are older than this change; the two added are 11 and 15 words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKUDdoyCtxHXm5Gcuze24W
FBumann
added this pull request to stack #583
September 20, 2026 20:35
FBumann
removed this pull request from stack #583
September 20, 2026 20:53
… check the loader makes (#581) * refactor(program): a direction carries what a consumer reads, not the check the loader makes `Direction.is_single_valued` is a module-private function in resolution.py. It is the discriminator between `at` and `sum(by=)`, it has two callers in one function, and no consumer asks it: a program's node type already says which operator a call became. The refusal table in docs/about/what-counts-as-public-api.md refuses a function whose answer a declaration could give. The `Predicate` union said it was what a lowered mask's root is built of. That is false. It also holds `ArithmeticComparison`, which lowering rewrites into an `ExpressionComparison`, so a consumer walking a program meets every other member and never that one. The comment and the reading page now say so. docs/reference/reading.md: n 52, avg 14.9, median 13, over25 7. The long sentences all predate this change; the two added are 11 and 9 words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKUDdoyCtxHXm5Gcuze24W * chore(resolution): the single-valued test is a local of the one call that asks it Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJfEUsCDtwXuXV8CANCHuR --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
FBumann
added this pull request to stack #587
September 20, 2026 21:15
#585 landed this branch's renames on main, and the two branches below carried them up. What is left here is the paragraph saying lowering rewrites every `ArithmeticComparison` into an `ExpressionComparison`, which needs #566's two nodes to be true, and two docstrings. Both conflicts were wording the base branch already carries: the row-building trees are `roots`, and the golden test's carrier note names a direction. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPqtQuarRGDmX2WrNVuKDP
FBumann
added a commit
that referenced
this pull request
Sep 20, 2026
…carries The `Predicate` union said it was what a lowered mask's `root` is built of. That is false here: it also holds `ArithmeticComparison`, which lowering rewrites into an `ExpressionComparison`, so a consumer walking a program meets every other member and never that one. These lines were #580's, which is where they were written. They are only true where the two nodes exist, and this is the branch that adds them. docs/reference/reading.md: the two sentences added are 11 and 9 words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPqtQuarRGDmX2WrNVuKDP
…0wpt' into wt/580
FBumann
removed this pull request from stack #587
September 20, 2026 21:35
FBumann
added a commit
that referenced
this pull request
Sep 22, 2026
* chore(language): a where comparison is one grammar rule over the expression grammar's arithmetic The where grammar's three comparison rules — a name against a literal, two relation columns, and position() against an integer — are one rule, side <op> side, where a side is the expression grammar's ARITHMETIC. What a side is, resolution decides with the schema in hand, and it hands back the same typed nodes with the same messages. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * test: the parser test names the validation class that holds the refusals it points at Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * chore(parser): the where depth measurement names the nodes it walks rather than Any `explicit-any` is an error on `src/math_spec` since #572, and that PR took only the fold's return type from #567, leaving `_nested` on this branch with a signature whose `Any` no longer even imports. `_ParsedWhere` is the union the measurement walks, which is #567's own answer for this file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V2SFmoxEF3SnaPKp7HbZTk * feat(language): a where may compare arithmetic over parameters Either side of a where comparison may be an expression over parameters: arithmetic, a reduction, a pullback, a translation with its edge, a macro, a named expression. A side is expanded, typed, degree-checked and dim-checked as an expression is, and refused where it names a variable or a dual. Two parameters compare the same way. The resolved tree holds ArithmeticComparisonNode over the core syntax tree, and lowering rebuilds every mask with ExpressionComparisonNode over program expressions. A case when: comparing expressions is refused as undecidable before the data arrives. expressions.md sentence lengths: n 68, avg 14.0, median 13, over 25 words 3 (base: n 56, avg 13.0, median 13, over 25 words 2). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * refactor(language): a comparison of expressions answers what it reads once, on the program's form The resolved form of the comparison had a second walk collecting the parameters and relations its sides read, and nothing asks a resolved mask that question: lowering rebuilds every mask before one reaches a consumer. The arm is the assertion the typesetter already carries for the lowered node. The one-line mask wrapper in lowering is inlined, and the two validation classes for what a where side may be are one. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * refactor(language): a namespace is built from its schema and carries it, so nothing passes both Namespace(schema) reads every declaration at construction; the eight argument constructor and the classmethod that was its only caller are gone. expression_of, _check_expression and _named took the schema and a namespace built from that same schema; they take the namespace. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * refactor(language): the single-text doors live with the tests that are their only callers expression_of and where_of had no caller in the package, and the two assertions that named expression_of as the door now name resolve_expression, which is the one the package walks through. The plain form of a where comparison is read by one method: a name that is a value against another is arithmetic, which used to be a second question asked after the first. The "prefix a context once" rule has one home in errors.py. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EEeM2YoAk4Xr2uWB5qwMsH * refactor(program): the branch's nodes follow the naming rule main now states #585 renamed the program's where vocabulary and expression nodes on main. This branch was written against the old names, and its own two comparison nodes arrived with the suffix the rule reserves for the core AST. Applying the same rename here first is what lets the base merge that follows agree line for line rather than conflict on every one of them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPqtQuarRGDmX2WrNVuKDP * docs(reading): the predicate union says which member a program never carries The `Predicate` union said it was what a lowered mask's `root` is built of. That is false here: it also holds `ArithmeticComparison`, which lowering rewrites into an `ExpressionComparison`, so a consumer walking a program meets every other member and never that one. These lines were #580's, which is where they were written. They are only true where the two nodes exist, and this is the branch that adds them. docs/reference/reading.md: the two sentences added are 11 and 9 words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JPqtQuarRGDmX2WrNVuKDP * docs(reading): a comparison against a literal is not an expression comparison A consumer walking a lowered mask gets ParameterComparison for `p_max > 5` and ExpressionComparison for `1 * p_max > 5`, though both mask the same coordinates. The page named only the second form. Gates: pytest tests/test_docs.py tests/test_reading_page.py (34 passed), the full suite (1383 passed, 1 skipped), mkdocs build --strict (clean, with the docs.python.org inventory dropped for the run, which this environment's proxy refuses with a 403), prettier --check (clean). Not run: typos, reuse lint, taplo, zizmor, compile-tex, for want of the tools. docs/reference/reading.md, by the measurement in the docs-writing skill: n 55, avg 14.6, median 13, over25 7. Every long sentence predates this change; the three added are 10, 20 and 9 words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJfEUsCDtwXuXV8CANCHuR * fix(language): a comparison with the literal first is refused as the order it is (#594) * fix(language): a where comparing two numbers, and a lone case comparing expressions, are refused at load A comparison with a number on each side is decided before any data arrives, and reached the program as an ExpressionComparison over two constants. A cases: block of one case escaped the undecidable refusal, which only looked at pairs. names_read on a mask over a cased entry dropped the data its regions are decided by. The relation refusal still said every other comparison tests a name against a literal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019tCWoetBmjF1LpbTbjQY29 --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
This PR is empty. Its diff against its base is nothing, and it should be closed rather than merged.
Where its work went:
mainalready hadExpressionComparisonandArithmeticComparisonThe last eleven lines moved to #566 because they are only true where its two nodes exist, and the repo keeps one issue to one PR.
How this branch got here
Merged, never rebased: the hard rule here is never to force-push.
maincame in at #566, was carried up through #569, and arrived here; each merge is on the branch it was made on.The suite passes on this head — 1446 passed — which is #569's suite, since this branch now adds nothing to it.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JPqtQuarRGDmX2WrNVuKDP