Update 2: I've realized that my original answer was correct and rolled back to the original, but will add some clarifying notes.
In Scheme, let*
allows later values to depend on earlier ones. So for instance, you can write (in the usual syntax):
(let* ((foo 3)
(bar (+ foo 1))
(baz (* bar 2)))
(* foo bar baz))
which binds foo
to 3, bar
to 4, baz
to 8, and returns 72. Your textbook's implementation allows for this.
However, your implementation doesn't allow this- it requires all the values to be evaluated independently. It is, however, a correct implementation of let
, just not of let*
.
The way your textbook's answer works is that the earlier values are bound before later ones.
So for instance, the above code in the textbook's implementation is as follows:
((lambda (foo)
((lambda (bar)
((lambda (baz) (* foo bar baz)) (* bar 2)))
(+ foo 1)))
3)
However, if you try to use your implementation in the same way:
((lambda (foo bar baz) (* foo bar baz)) 8 (+ foo 1) (* bar 2))
; Error - foo and bar aren't bound
then the foo
in (+ foo 1)
will be unbound, as foo
isn't in scope there (same for the bar
in (* bar 2)
.
As a side note, the (e)
in your implementation should really just be e
, as in the textbook's implementation; the former is a thunk call, while the latter is just an expression.