[plt-scheme] How is letrec different from letrec* in its use?
On Fri, Feb 13, 2009 at 11:01:14PM -0600, Grant Rettke wrote:
> On Fri, Feb 13, 2009 at 6:35 AM, James Coglan <jcoglan at googlemail.com> wrote:
> >> 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?
>
> > (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)))
>
> This is how I interpreted its behavior from the spec:
>
> (define-syntax my-letrec
> (syntax-rules ()
> ((_ ((var init) ...) body)
> (let ((var #f) ...)
> (set! var init) ...
> body))))
>
> (my-letrec
> ((a (lambda (n) (when (< n 5) (b (add1 n)))))
> (b (lambda (n) (when (< n 5) (a (add1 n))))))
> (a 0))
>
> #;(let ((a #f)
> (b #f))
> (set! a (lambda (n) (when (< n 5) (b (add1 n)))))
> (set! b (lambda (n) (when (< n 5) (a (add1 n)))))
> (a 0))
>
> Are we saying the same thing? Is this right?
>
> > 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)))
>
> I see. This allow for mutually recursive definitions; but as Sam said
> you can predict about behavior in situations when you are not *only*
> binding lambda expressions.
>
> I am wondering why would people use letrec for anything other than
> binding lambda expressions if it is impossible to reason about its
> behavior? Or rather, why would it allow anything other than lambda
> expressions to be bound if you can't predict the behavior?
Might there be constructions like
(letrec ([f (cons (lambda() foo) (lambda() bar))]
[foo (lambda() ...f...)]
[bar ...]
)
)
-- hendrik