Repository navigation
Conversation
`dimensions.md` states the frame law and the four invariants the notation is held to, above the bullets that were already its consequences. Two of the five were on the page (the key is fixed, a call brings the dims it lands on) and stay in their bullets, which carry the worked example each needs; three were nowhere. The law is the one the loader computes, checked against it line by line: `_sum_dims` and `_at_dims` both return `(operand − consumed) ∪ produced`, `_check_joined` holds the operand to `consumed ∪ joined`, and `_check_lands_clear` refuses on `(produced ∩ operand) − consumed`. The joined set is `key − (consumed ∪ produced)`, which is symmetric: for `sum` it reduces to `key − consumed`, for `at` to `key − produced`. The block says "a call" throughout rather than "a walk", so it reads the same whichever way #494 goes. Sentence length on the page: n 117, avg 16.8, median 17, 13 over 25 — against n 105, avg 17.0, median 17, 13 over 25 before, so the block adds no long sentence. `mkdocs build --strict` clean, `tests/test_docs.py` 33 passed, prettier and typos clean. The page is not generated, so no generator was involved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUhbXWGiyZF46wHp3fVnr2
`sum` consumes a key column and `at` consumes none — the sixth rule, and the only one that says whether a call is allowed rather than what it computes or what survives an edit. It is exactly the check in the code. A column is consumed, produced or joined, so `key <= produced | joined`, which `Direction.is_function_read` computes, holds precisely when no key column was consumed. `at` needs it true and `sum` needs it false. Stated as one line because the fuller reading — sum lands on a value, at lands on a key — is the common case rather than the law, and the loader accepts two calls it would refuse: `sum(p, by=connection, over=generator, into=bus)` lands on a key column, because a bare relation has no value columns; and `at(cap_bg, by=gen_bt, over=bus, into=technology)` lands on a value column, because the key is covered by the join rather than by the result. Both were run against the loader. The section's prose above the block still teaches the common case, which is what it is for. Sentence length on the page: n 118, avg 16.8, median 17, 13 over 25 — unchanged from the previous commit but for the added sentence. `mkdocs build --strict` clean, `tests/test_docs.py` 33 passed, prettier and typos clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUhbXWGiyZF46wHp3fVnr2
…es reach Two tables. The first says what `over=` and `into=` may name on each operator, which is rule 6 and nothing else: `sum` consumes at least one key column, `at` consumes value columns only, and either end may name any subset otherwise. Both were run against the loader, including the mixed cases — `sum(x, by=gen_bt, over=[generator, bus], into=technology)` consumes a key and a value together, and `at(cap, by=gen_bt, over=bus, into=[generator, technology])` produces one of each. The second says which rules reach the other two ways to read a relation. A partition moves no frame, so the frame law is silent; rule 4 holds with force, and rule 3 holds only where the call writes `within=`. A `where` builds no direction at all. That last gap is a real one rather than a wording: `within=` omitted means every value column, so a relation that gains one regroups every partition through it. The page says so and cites #538, which proposes the fix. Sentence length on the page: n 131, avg 16.8, median 16, 14 over 25 — against n 105, avg 17.0, median 17, 13 over 25 before the rules block. `mkdocs build --strict` clean, which is what checks the new `#where-the-rules-reach` anchor and the link into `#partitions`. `tests/test_docs.py` 33 passed, prettier and typos clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUhbXWGiyZF46wHp3fVnr2
…re the rules The section opened on the mechanics of a call. It now opens on the division of labour: a relation says which rows exist and what identifies them, and an operator says what to do with the rows a coordinate finds. The key is the hinge — consume a key column and many rows share what is left, leave it whole and one row is found. One table puts every use of a relation on that single axis: many rows added up is `sum`, one row read is `at`, one row as a group label is a partition, one row or none as an answer is a `where`. Only the first finds more than one, which is why only `sum` adds anything up — rule 6 as the reader meets it rather than as a law. The table `Where the rules reach` listed the same four categories one screen below, so it goes; its prose stays, since what it says about partitions and `where` is not in the new table. Sentence length on the page: n 136, avg 16.8, median 16, 15 over 25. `mkdocs build --strict` clean, which checks the two links out of the new table. `tests/test_docs.py` 33 passed, prettier and typos clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUhbXWGiyZF46wHp3fVnr2
Contributor
Author
|
Superseeded |
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.
What this changes
dimensions.mdgains the six rules, a table of what each end of a call may name, and a table of how far the rules reach. Docs only — the language is untouched.over=, consumedinto=, producedsumatsumandatshift,sum_back,positionwhereRules 4 and 5 were already on the page as bullets and stay there too, because each carries the worked example and the rewrite a reader needs.
Why
These are the rules the loader already keeps, and a future syntax proposal is measured against them — which needs them written down first, or the next revisit re-derives them.
One gap the writing found
Rule 3 does not hold for partitions.
within=is optional, and omitted it means every value column, so a relation that gains one regroups everyshift,sum_backandpositionthrough it:The page says so and cites #538, which proposes making
within=required whenby=is present — the mechanismsumandatalready use. That is a language change and is not in this PR.Each rule checked against the loader
_sum_dimsreturns(inner - by.dimensions) | by.intoand_at_dimsreturns(inner - by.into) | by.dimensions— the same law, sincedimensionsis the fine side andintothe coarse one._check_joinedholds the operand to the joined dims;_sum_dimsand_at_dimshold it to the consumed ones. Together: the operand carriesconsumed ∪ joined._check_lands_clearrefuses onsorted((produced & inner) - consumed), which is rule 5 verbatim. The− consumedterm is what lets a relation into its own dimension through.joinedis built as the key roles in neitherover=norinto=, sokey − (consumed ∪ produced). The draft of rule 1 said "the keys not consumed in a sum", which holds forsumalone; the symmetric form reduces tokey − consumedforsumandkey − producedforat.Direction.is_function_read, which computeskey <= produced | joined. Since a column is consumed, produced or joined, that holds precisely when no key column was consumed.sum(x, by=gen_bt, over=[generator, bus], into=technology)consumes a key and a value together, andat(cap, by=gen_bt, over=bus, into=[generator, technology])produces one of each. Both load.Why rule 6 is one line
The fuller reading —
sumlands on a value,atlands on a key — is the common case rather than the law, and as a rule it would refuse two calls the loader accepts:What holds without exception is that
atconsumes only value columns, and that the key columns named at neither end are joined on. The section's prose above the block still teaches the common case, which is what prose is for.Interaction with #494
The block says "a call" throughout, never "a walk", so it reads the same whichever way that PR goes. It is based on
main, so if #494 lands first this needs a rebase for the section heading alone (### Walks→### Directions), and nothing in the block itself moves.Gates
pixicannot be installed here —pixi.shis refused by this environment's egress proxy — so the gates ran from a pip environment on Python 3.13.mkdocs build --strictclean, which is what checks the new#where-the-rules-reachanchor and the link into#partitions; the remote intersphinx inventory was dropped, which the proxy also refuses.tests/test_docs.py: 33 passed. prettier and typos clean. The page is not generated, so no generator was involved.Sentence length on the page: n 131, avg 16.8, median 16, 14 over 25 — against n 105, avg 17.0, median 17, 13 over 25 before.
🤖 Generated with Claude Code
https://claude.ai/code/session_01NUhbXWGiyZF46wHp3fVnr2