(Lispex)sicp.io
3.11 · Internal definitions and local procedure groups

Internal names can describe one cooperating local program.

A procedure invocation can create a private environment for several named helpers, including mutually recursive helpers whose references become meaningful after the local definitions are installed.

Guiding question

How can several local procedures refer to one another without leaking their names into the surrounding environment?

  • Distinguish a local definition from a global binding
  • Follow mutually recursive helpers through one invocation environment
  • Explain why helper references are resolved when the closures are applied
  • Model scan-out as bindings created before assignments install procedure values
  • Keep an explicit unassigned marker separate from a valid procedure value

classify-parity creates even-step and odd-step inside each call. Both closures share the invocation environment, so even-step can call odd-step and odd-step can call even-step even though neither name becomes global. The calls happen only after both local definitions have been processed. A fresh call to classify-parity creates another private group of bindings.

The second program treats definitions as quoted data and builds the scan-out shape used to reason about simultaneous local scope: create every name with an explicit unassigned marker first, then install each procedure with set!, then evaluate the remaining body. This run constructs the transformation as data; it does not execute the generated form or claim that every Scheme implementation must expose the same intermediate representation.

Lispex · SICP sourceScheme-compatible SICP syntax executed by the Lispex SICP profile.
(begin
  (define (classify-parity n)
    (define (even-step value)
      (if (= value 0)
          #t
          (odd-step (- value 1))))
    (define (odd-step value)
      (if (= value 0)
          #f
          (even-step (- value 1))))
    (list (even-step n) (odd-step n)))
  (list (classify-parity 7)
        (classify-parity 8)))
Lispex learning runtimeLispex SICP profile 1.0.0
Loading Lispex SICP runtime
Lispex · SICP source333 / 1,048,576 UTF-8 bytes
Examples
Result
Output
Value
Diagnostic
Visible execution0 / 0 trace events
    This browser result is not a Lispex Vouch record or authority.wasm —
    Expected observation

    The first program returns ((#f #t) (#t #f)). The second returns a let form with even-step and odd-step bound to quoted *unassigned* markers, followed by two set! forms and the original body.

    Trace focus

    In the first run, find the environment created by classify-parity and follow alternating applications without a global even-step or odd-step lookup. In the second, separate reading quoted definition data from constructing bindings, lambda values, assignments, and the final body. The generated form is an explanatory model of this finite input, not a trace of a compiler pass inside the runtime.

    Try it yourself

    Change the program before you read the hint.

    Add a local divisible-by-three? helper group that cycles through three mutually recursive procedures. Keep all helper names inside one public classifier and predict the results for 8 and 9.

    Show one hint

    Each helper represents one remainder class and calls the next helper after subtracting 1. Only the remainder-zero helper returns true at zero.