<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I just read the spec for both letrec and letrec* and I see that the<br>

former is not evaluted in any other but the latter is evaluted from<br>
left to right. I am not getting the difference in their use. May<br>
someone please provide an illuminating example?</blockquote><div><br><br>I find it&#39;s helpful to expand (let) expressions as lambdas to see what&#39;s going on. It shows up how each variable is scoped and also shows where execution order is important.<br>
<br>(let) simply makes a lambda in the current scope and calls it with the given arguments:<br><br>(let ([x 1]<br>      [y 2])<br>  (+ x y))<br><br>is equivalent to:<br><br>((lambda (x y)<br>   (+ x y))<br> 1 2)<br><br>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.<br>
<br>(let* ([x 1]<br>       [y 2])<br>  (+ x y))<br><br>is equivalent to:<br><br>(let ([x 1])<br>  (let ([y 2])<br>    (+ x y)))<br><br>(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)).<br>
<br>(letrec ([x 1]<br>         [y 2])<br>  (+ x y))<br><br>is equivalent to:<br><br>((lambda ()<br>  (define x 1)<br>  (define y 2)<br>  (+ x y)))<br><br>Finally, (letrec*) is like (let*) but it uses (letrec).<br><br>(letrec* ([x 1]<br>
          [y 2])<br>  (+ x y))<br><br>is equivalent to:<br><br>(letrec ([x 1])<br>  (letrec ([y 2])<br>    (+ x y)))<br></div></div><br><br>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.<br>