# [plt-scheme] How is letrec different from letrec* in its use?

>* I just read the spec for both letrec and letrec* and I see that the
*>* former is not evaluted in any other but the latter is evaluted from
*>* left to right. I am not getting the difference in their use. May
*>* someone please provide an illuminating example?
*
I find it's helpful to expand (let) expressions as lambdas to see what's
going on. It shows up how each variable is scoped and also shows where
execution order is important.
(let) simply makes a lambda in the current scope and calls it with the given
arguments:
(let ([x 1]
[y 2])
(+ x y))
is equivalent to:
((lambda (x y)
(+ x y))
1 2)
So the values of x,y are evaluated *outside* the scope of the lambda. (let*)
is a shorthand for nesting (let)s, so each value is evaluated in the scope
of the previous enclosing (let). Here execution order is important because
each evaluation must have access to the value of the preceeding evaluations.
(let* ([x 1]
[y 2])
(+ x y))
is equivalent to:
(let ([x 1])
(let ([y 2])
(+ x y)))
(letrec) is like (let), but the evaluations take place *inside* the lambda,
changing their scope. The evaluations are not supposed to depend on each
other so evaluation order is not important (like for (let)).
(letrec ([x 1]
[y 2])
(+ x y))
is equivalent to:
((lambda ()
(define x 1)
(define y 2)
(+ x y)))
Finally, (letrec*) is like (let*) but it uses (letrec).
(letrec* ([x 1]
[y 2])
(+ x y))
is equivalent to:
(letrec ([x 1])
(letrec ([y 2])
(+ x y)))
Hopefully you can see how if we replaced 1,2 in these examples with
expressions, lambdas, etc, the differences in scoping affect the outcomes.
(let*) and (letrec*) impose an evaluation order because they imply a fixed
nesting order for scopes and thus affect the visibilty of variables within
lambdas assigned to other variables.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20090213/81f475a0/attachment.html>