Skip to content

docs: the slot-scopes number bounds half the question, not all of it - #75

Merged
fadion merged 1 commit into
masterfrom
docs/slot-scopes-precision
Aug 27, 2026
Merged

fadion merged 1 commit into
masterfrom
docs/slot-scopes-precision

Conversation

@fadion

@fadion fadion commented Aug 27, 2026

Copy link
Copy Markdown
Owner

#74 said the deep-versus-shallow name lookup difference was "the ceiling on what slots could win". It is not, and that is the kind of overclaim that gets read later as a settled answer.

Both benchmarks pay exactly one successful map lookup. What differs is the failed lookups at the scopes in between, so the fifth-more-time figure bounds chain-walking and says nothing about the other half of the change — replacing that final map lookup with an array index. No benchmark in the file can see that half, and none was built to.

What changed

  • Rewrote the Known Gaps entry to say which half is measured and which is not.
  • Recorded that the cheaper half stands alone: Ref.Hops already says how far up a binding lives, so the evaluator could walk exactly that many parents and do one map lookup instead of up to Hops + 1. That collects the entire measured difference while vars stays a map, with no scope sizes to plumb and no change to define or assign.
  • Recorded why either version is bigger than swapping a data structure: the evaluator has no runtime dependency on resolution at all — i.info is assigned in two places and read in none. The paths that would still need names are real: the REPL's :vars walks globals.vars, an aliased import builds its module from scope.vars[name], and four New(file, nil) call sites have no Info to consult.
  • Tightened the same loose claim in the benchmark's own comment, which is where somebody actually reads it.

No behaviour changed.

#74 said the deep-versus-shallow name lookup difference was "the ceiling on
what slots could win". It is not, and the overclaim is the kind that gets
read later as a settled answer.

Both benchmarks pay exactly one successful map lookup. What differs between
them is the failed lookups at the scopes in between, so the fifth-more-time
figure bounds chain-walking and says nothing about the other half of the
change: replacing that final map lookup with an array index. No benchmark
in the file can see that half, and none of them was built to.

Two things worth writing down while correcting it.

The cheaper half stands alone. Ref.Hops already records how far up a
binding lives, so the evaluator could walk exactly that many parents and do
one map lookup instead of up to Hops + 1. That collects the entire measured
difference with `vars` still a map, no scope sizes plumbed anywhere, and
define and assign untouched.

And either version is a bigger step than swapping a data structure, because
the evaluator has no runtime dependency on resolution at all: i.info is
assigned in two places and read in none. Both would introduce one. The
paths that would still need names are real -- the REPL's :vars walks
globals.vars, an aliased import builds its module from scope.vars[name],
and four New(file, nil) call sites have no Info to consult at all.

The benchmark's own comment said the same loose thing and now says which
half it measures, since that is where somebody reads it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@fadion
fadion merged commit 21b5f50 into master Aug 27, 2026
8 checks passed
@fadion
fadion deleted the docs/slot-scopes-precision branch August 27, 2026 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant