Exercise 4.8.  ``Named let'' is a variant of let that has the form

(let <var> <bindings> <body>)

The <bindings> and <body> are just as in ordinary let, except that <var> 
is bound within <body> to a procedure whose body is <body> and whose 
parameters are the variables in the <bindings>. Thus, one can repeatedly 
execute the <body> by invoking the procedure named <var>. For example, 
the iterative Fibonacci procedure (section 1.2.2) can be rewritten using 
named let as follows:

(define (fib n)
  (let fib-iter ((a 1)
                 (b 0)
                 (count n))
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1)))))

Modify let->combination of exercise 4.6 to also support named let.

————————————————————————————————————————————————————————————————————————


(define (eval exp env)
  (cond ...
        ((let? exp) (eval (let->combination exp) env))
        ...))

(define (let? exp) (tagged-list? exp 'let))
(define (let-body exp) (if (named-let? exp)
                           (cadddr exp)
                           (caddr exp)))
(define (let-bindings exp) (if (named-let? exp)
                               (caddr exp)
                               (cadr exp)))
(define (named-let? exp) (and (tagged-list? exp 'let)
                              (symbol? (cadr exp))))
(define (named-let-name exp) (cadr exp))

(define (let->combination exp)
  (if (named-let? exp)
      (make-let
        (list (list (named-let-name exp)
                    (make-lambda (map car (let-bindings exp))
                                 (let-body exp))))
        (make-application (named-let-name exp)
                          (map cadr (let-bindings exp))))
      (make-application
        (make-lambda (map car (let-bindings exp))
                     (let-body exp))
        (map cadr (let-bindings exp)))))
