docs(machine/README): scope rules for indexed forms + call(name)#110
Merged
Conversation
Two scope rules were implicit before — only shown by example in the
Subroutines section, never stated. Making them explicit:
1. The `ix` in any indexed form (`mark(ix)`, `check(ix1, ix0)`, `call(_, ix)`
etc.) references the scope the call is written in. Lexical resolution;
no implicit jump to top-level from inside a subroutine.
2. `call(name)`'s name resolves by walking the lexical scope chain from
the current scope outward, first match wins. Subroutines nest, and a
`call('foo')` from inside `outer` finds `outer.foo` before checking
the top-level program.
Adds a short "Scope rules for indexed forms" subsection right after the
Author's extensions table, plus a TOC pointer. Prose only — no
executable examples — so no test changes.
The rules were established during machines-demo#114 Phase 2 (cross-ref
linter) work where I had to ask twice to be sure of `call(name, ix)`'s
scope. With them written down, anyone (or any tool) building on the
engine can pick them up directly.
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.
Summary
Two scope rules were implicit in the README before — shown by example in the Subroutines section but never stated as rules. Making them explicit removes the kind of ambiguity that bites consumers and tooling.
The rules being added
The `ix` in any indexed form references the scope the call is written in. Applies to `mark(ix)`, `erase(ix)`, `noop(ix)`, `left(ix)`, `right(ix)`, `check(ix1, ix0)`, and `call(name, ix)`'s second arg. Top-level when at top; subroutine-local when inside a subroutine body. No implicit jump to top-level from within a subroutine.
`call(name)` resolves names by walking the lexical scope chain from the current scope outward, first match wins. Subroutines can nest — a `call('inner')` from inside `outer` finds `outer.inner` before checking the top-level program. This mirrors identifier resolution in lexically-scoped languages, and matches the path notation (`foo::bar::1`) already documented at "Naming convention".
Where it lives
A new "Scope rules for indexed forms" subsection right after the Author's extensions table in the Commands section, plus a TOC pointer. Placed BEFORE the Subroutines section so a reader encountering `mark(20)` / `check(20, 40)` examples knows what they mean. A short scope-of-the-literal-arg table covers the common cases without bloating the section.
Why now
The rules surfaced during a cross-reference linter for the demo (the linter validates literal arg references against the surrounding `new PostMachine({ … })`). To get `call(name, ix)`'s scope right I had to ask twice; an initial "subroutines are flat / always top-level" reading was corrected to "subroutines nest / lexical chain." Writing the rules down means the next person (or tool) gets them on the first read.
Test plan