sicp.io
Chapter 1 · Checkpoint

Resolve the name. Choose the path. Preserve the boundary.

Use seventeen runnable programs to reconnect all eighteen Chapter 1 lessons. Predict values and paths first, identify the binding or abstraction boundary that matters, then explain what the visible process adds to the final result.

Guiding question

Can you explain which environment supplies a name, which predicate selects work, what a procedure keeps private, how lambda constructs behavior, what a primality test establishes, and how the resulting process grows?

  • Read an operator and its operands as one combination
  • Explain how definitions, parameters, and let bindings resolve a name
  • Construct applicative-order and normal-order substitution paths as data
  • Follow cond, if, and short-circuit predicate paths
  • Separate a public procedure contract from local helper bindings
  • Explain which call environment supplies a procedure parameter
  • Contrast recursive and iterative process shapes
  • Follow a procedure passed as an argument
  • Construct and apply anonymous procedures with lexical scope
  • Build a new transformation by returning and composing procedures
  • Preserve an invariant while reducing a problem
  • Refine a numerical guess through a fixed iterative process
  • Accumulate a finite continued fraction from its final term
  • Search for a fixed point by feeding each transformed value into the next step
  • Reduce an exponent while preserving a product invariant
  • Reduce modular powers and limit a fixed-base Fermat conclusion
  • Distinguish trial-division evidence from probable-prime evidence
  • Compare tree-recursive call growth with linear iterative state transitions

Begin with names and substitution. The environment example separates global, parameter, and let-local bindings. The substitution data then contrasts reducing an operand before insertion with inserting the expression first; those lists explain a simple application rather than expose hidden Lispex frames.

Next follow control. cond selects the first matching clause, if protects division by zero, and the short-circuit forms leave unreachable record! calls absent. Only #f is false, so a quoted symbol can select a true branch.

The black-box example keeps choose and square local while preserving one public procedure contract. Two implementations use different internal decompositions while callers depend only on the inputs and result. The matching finite examples confirm the shared result for the displayed inputs.

Compare the two factorial processes, then follow procedures as values. sum receives term and next, a nested lambda finds bindings lexically, and compose constructs a procedure whose captured behavior runs only after a later application.

Euclid preserves the greatest common divisor while shrinking the pair. Square-root improvement, continued fractions, and fixed points each carry a different complete next state. Fast exponentiation and expmod preserve explicit numeric relationships while reducing the remaining problem.

Finally compare primality procedures. Trial division proves the displayed small candidates by exhausting the square-root boundary, while selected Fermat bases can still accept Carmichael 561. Then contrast the repeated Fibonacci call tree with a fixed-size iterative state.

SICP code227 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 environment program returns ((global-x 10) (parameter-x 3 local-y 4 sum 7) (global-after 10)). The substitution program returns the applicative and normal reduction lists ending in 25. The conditional program returns (negative zero small-positive large-positive undefined 5 truthy). The black-box program returns (13 61 global-marker). Both factorial programs return 40320. The higher-order sum returns 55. The nested lambda program returns (100 7 100). Returned-procedure composition returns (49 37 15). Euclid returns 2. The square-root, continued-fraction, fixed-point, exponentiation, and modular programs retain their lesson results. The primality comparison returns ((prime-7 #t #t) (composite-15 #f #f) (carmichael-561 #f #t)). The Fibonacci measurement returns (21 67 8).

    Trace focus

    Locate the nearest environment binding, then distinguish quoted substitution data from actual applications. Follow each selected predicate branch and verify skipped calls are absent. Enter and leave local black-box helpers without confusing them with global names. Separate lambda creation from application, follow procedure-valued arguments and returned procedures, then inspect Euclid, numerical improvement, exponent reduction, modular reduction, trial divisors, selected Fermat bases, and repeated Fibonacci calls. Every trace records the exact selected finite run under the declared runtime limits.

    Review

    Seventeen short checks for your own explanation

    Why does x denote 3 inside describe but remain 10 outside?

    Answer The call creates a nearer parameter binding x = 3, while the surrounding global binding remains unchanged after the call returns.

    Why does the normal substitution path contain two copies of (+ 2 3)?

    Answer The body uses x twice, so inserting the unevaluated operand duplicates that expression before either copy is reduced.

    Why do the expressions after #f in and and after selected in or not run?

    Answer and already knows its result at the first false value, and or already knows its result at the first non-#f value.

    Why does the local choose helper not replace the global choose binding?

    Answer Block structure creates a distinct local binding whose lifetime and visibility match the public procedure body.

    Why can equal factorial results come from different processes?

    Answer A value records the answer, while the order and amount of pending work determine the process that produces it.

    What makes sum a higher-order procedure?

    Answer It accepts term and next as procedure values and applies them while traversing the interval.

    Where does the inner lambda find x and y?

    Answer It finds y in its own call environment and x in the surrounding lexical environment created by the outer lambda.

    When does a procedure returned by compose use its captured f and g?

    Answer compose constructs the new procedure first; f and g run only when that returned procedure later receives an argument.

    What remains unchanged while Euclid’s arguments shrink?

    Answer The set of common divisors, and therefore the greatest common divisor, is preserved across each remainder pair.

    Why does the square-root process carry only one guess forward?

    Answer The improvement rule can compute the next guess entirely from the current guess and unchanged target.

    What does a fixed-limit execution trace record?

    Answer It records the exact evaluation events reached by the selected program and input.

    Why does the continued fraction begin at the final term?

    Answer Each outer layer needs an already completed suffix, so carrying the suffix from k toward 1 keeps the state complete.

    What makes the fixed-point stopping rule explicit?

    Answer The remaining count is part of every call state, and reaching zero returns the current guess.

    Why can an even exponent be halved after the base is squared?

    Answer The squared base raised to half the exponent equals the original base raised to the even exponent.

    What does one passing base-2 congruence establish?

    Answer It establishes that the candidate satisfies that selected congruence. Composite 561 supplies the contrasting classification.

    What does Carmichael 561 demonstrate about several Fermat bases?

    Answer It is composite by trial division yet passes the displayed coprime bases, so the Fermat procedure reports a probable-prime result for those bases.

    Why do recursive Fibonacci calls grow much faster than iterative steps?

    Answer Each non-base recursive call creates two overlapping subproblems, while the iterative state advances once per index.