4.6 Exercise 4.6

We can transform let expressions using the same pattern as in the last problem. First, the requisite bindings:

(define (let? exp) (tagged-list? exp 'let))
(define (let-bindings exp) (cadr exp))
(define (let-body exp) (cddr exp))
(define (let-names exp) (map car (let-bindings exp)))
(define (let-values exp) (map cadr (let-bindings exp)))

And now, using them to construct an immediately-invoked lambda expression:

(define (let->combination exp)
  (list (make-lambda (let-names exp) (let-body exp))
        (let-values exp)))

We also need to add a line to eval, dispatching on whether we have a let expression. This must come before normal function application, as let is a special form.

...

((let? exp) (eval (let->combination exp) env))

...