Bindings, Scope, Cells, and Mutation

Every lexical binding is a mutable cell. Closures capture frames and therefore share later set! updates to the same cell.

At a glance

LISPEX
(define x 1)
(define get (lambda () x))
(set! x 2)
(get)

Result

OUTPUT
2

Current guarantees

  • Lookup chooses the nearest lexical cell; shadowing does not mutate an outer binding.
  • letrec allocates cells before initializers and raises E321 when an uninitialized cell is read.
  • A duplicate top-level define updates the existing global cell, preserving earlier closure references.

Boundaries

  • set! on an unbound name is E303; it never creates a binding.
  • The internal uninitialized sentinel cannot be represented as a guest value.