A lexical address replaces a name search with two indexes.
A compiler can encode a variable as a frame depth and binding offset, allowing the machine to fetch its value directly from the runtime environment.
What environment knowledge can compilation move out of runtime lookup?
- Represent a lexical address as frame depth and binding offset
- Select a runtime frame without inspecting variable names
- Select one value slot inside that frame
- Connect compile-time name search to runtime direct lookup
The address (depth offset) counts outward through environment frames, then across one frame. lexical-ref follows only those two numbers. The runtime frames contain values rather than name-value pairs, so no assoc or symbol comparison occurs during the fetch.
find-address performs the name search against the compiler environment, whose frames contain variable names. Once it produces (1 0) for x, the runtime can use that address to fetch 42 from matching value frames. The example makes the compiler and machine agree on one frame layout.
(begin
(define (frame-at environment depth)
(if (= depth 0)
(car environment)
(frame-at (cdr environment) (- depth 1))))
(define (lexical-ref address environment)
(list-ref (frame-at environment (car address))
(cadr address)))
(define environment '((10 20) (30 40 50)))
(list (lexical-ref '(0 1) environment)
(lexical-ref '(1 0) environment)
(lexical-ref '(1 2) environment)))- Output
- —
- Value
- —
- Diagnostic
- —
The first program returns (20 30 50). The second resolves x to address (1 0), then returns ((1 0) 42).
In the first run, follow depth recursion separately from list-ref offset selection and confirm that no variable symbol is searched. In the second run, separate the compile-environment name search from the later value-frame lookup.
Change the program before you read the hint.
Add w after z in the innermost compile-time frame and add 11 to the matching runtime frame. Predict the address and value of w.
Show one hint
The innermost frame has depth 0. Its second slot has offset 1.