Is Scheme's letrec
only meant for defining procedures, especially recursive ones? I am asking because it appears to be possible to bind non-procedures using letrec
. For example, (letrec ((x 1) (y 2)) (+ x y))
. If Scheme's letrec
is only meant for procedures, then why isn't its syntax constrained to allow procedures only?
Consider this use of letrec
to define two mutually recursive procedures:
(letrec ((is-even? (lambda (n)
(let ((n (abs n)))
(if (= n 0)
#t
(is-odd? (- n 1))))))
(is-odd? (lambda (n)
(let ((n (abs n)))
(if (= n 0)
#f
(is-even? (- n 1)))))))
(is-even? 123))
If we use Common Lisp's LABELS
instead of Scheme's letrec
, these two mutually recursive procedures would be defined like this instead:
(labels ((even-p (n)
(let ((n (abs n)))
(if (= n 0)
t
(odd-p (- n 1)))))
(odd-p (n)
(let ((n (abs n)))
(if (= n 0)
nil
(even-p (- n 1))))))
(even-p 123))
If letrec
is only useful for defining procedures, then why isn't its syntax constrained like that of LABELS
to allow only procedures in its initialization forms?