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

Log in or register to write something here or to contact authors.