docs: the slot-scopes number bounds half the question, not all of it - #75
Merged
Merged
Conversation
#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>
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.
#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
Ref.Hopsalready says how far up a binding lives, so the evaluator could walk exactly that many parents and do one map lookup instead of up toHops + 1. That collects the entire measured difference whilevarsstays a map, with no scope sizes to plumb and no change todefineorassign.i.infois assigned in two places and read in none. The paths that would still need names are real: the REPL's:varswalksglobals.vars, an aliased import builds its module fromscope.vars[name], and fourNew(file, nil)call sites have noInfoto consult.No behaviour changed.