sicp.io
1.1.2 · Naming and the environment

A name gets its value from a particular environment.

Definitions create bindings that expressions look up. Procedure calls and let expressions add local bindings without changing the surrounding environment.

Guiding question

How does the evaluator decide which value a name denotes when global definitions, parameters, and local names coexist?

  • Read define as creating a binding rather than replacing a symbol in the source
  • Follow later expressions that look up previously defined names
  • Distinguish a global environment from a procedure-call environment
  • Recognize a parameter that shadows an outer name
  • Keep let-local names from leaking into the surrounding environment

A definition associates a name with a value in the current environment. rectangle-area is not textual shorthand for (* width height); it is a separate binding whose value is computed when the definition runs. Later list construction looks up width, height, rectangle-area, and perimeter by name in the same environment.

Calling describe creates a new environment where the parameter x is bound to 3 even though the surrounding environment already has x bound to 10. The inner let adds y to that call environment. Lookups in the body find the nearest matching binding first, so x denotes 3 inside the call and 10 before and after it outside. The local y disappears when the call returns.

SICP code187 of 1,048,576 UTF-8 bytes
Examples
Result
Output
Value
Diagnostic
Execution trace0 / 0 events
    Programs run in the browser with their result and execution trace.
    Expected result

    The definition program returns (3 4 12 14). The shadowing program returns ((global-x 10) (parameter-x 3 local-y 4 sum 7) (global-after 10)).

    Trace focus

    In the first run, separate the evaluation that computes each definition from later symbol lookups that retrieve the stored values. In the second, find the environment created for describe, the parameter binding x = 3, and the additional let binding y = 4. Compare those lookups with the global x = 10 before and after the call. The trace records this finite environment history with pedagogical frame labels.

    Try it yourself

    Change the program and compare the result.

    Add a global y equal to 100, keep the local let binding named y, and return both the inner describe result and the global y after the call. Predict which lookup each y reference uses.

    Show hint

    The local y is nearer while the procedure body runs. After the call returns, only the global y remains visible.

    Complete this lesson

    0 of 18 lessons complete in this chapter0%