<< Previous exercise (4.7) | Index | Next exercise (4.9) >>


 (define (named-let? expr) (and (let? expr) (symbol? (cadr expr)))) 
 (define (named-let-func-name expr) (cadr expr)) 
 (define (named-let-func-body expr) (cadddr expr)) 
 (define (named-let-func-parameters expr) (map car (caddr expr))) 
 (define (named-let-func-inits expr) (map cadr (caddr expr))) 
 (define (named-let->func expr) 
     (list 'define  
           (cons (named-let-func-name expr) (named-let-func-parameters expr)) 
           (named-let-func-body expr))) 
 (define (let->combination expr) 
     (if (named-let? expr) 
           (list (named-let->func expr) 
                 (cons (named-let-func-name expr) (named-let-func-inits expr)))) 
         (cons (make-lambda (let-vars expr) 
               (list (let-body expr))) 
               (let-inits expr)))) 


While the above should work, the problem with doing it with define is that it raises the possibility of nameclash issues, as define directly installs the name of the lambda in the named let into the current frame of the environment. The other possibility, which allows greater control of scope is to do it with the usual let, adding an arbitrary binding for var which is then reassigned in the body of the let expression (with a set! command) to the needed lambda before anything else is evaluated...