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