Prev Up Next
If we wanted the above procedures as local
variables, we could try to use a `let` form:

(`let` ((**local-even?** (`lambda` (**n**)
(`if` (**=** **n** *0*) *#t*
(**local-odd?** (**-** **n** *1*)))))
(**local-odd?** (`lambda` (**n**)
(`if` (**=** **n** *0*) *#f*
(**local-even?** (**-** **n** *1*))))))
(**list** (**local-even?** *23*) (**local-odd?** *23*)))

This won't quite work, because the occurrences of
**local-even?** and **local-odd?** in the initializations
don't refer to the lexical variables themselves.
Changing the `let` to a `let*` won't work either,
for while the **local-even?** inside **local-odd?**'s body
refers to the correct procedure value, the **local-odd?**
in **local-even?**'s body still points elsewhere.

To solve problems like this, Scheme provides the form
`letrec`:

(`letrec` ((**local-even?** (`lambda` (**n**)
(`if` (**=** **n** *0*) *#t*
(**local-odd?** (**-** **n** *1*)))))
(**local-odd?** (`lambda` (**n**)
(`if` (**=** **n** *0*) *#f*
(**local-even?** (**-** **n** *1*))))))
(**list** (**local-even?** *23*) (**local-odd?** *23*)))

The lexical variables introduced by a `letrec` are
visible not only in the `letrec`-body but also within
all the initializations. `letrec` is thus
tailor-made for defining recursive and mutually
recursive local procedures.

Prev Up Next