SICP Practice

Practice 4.16

a

(define (lookup-variable-value var env)
  (define (env-loop env)
    (define (scan vars vals)
      (cond ((null? vars)
             (env-loop (enclosing-environment env)))
            ((eq? var (car vars)) 
             (if (eq? (car vals) '*unassigned*)
                 (error "Unassigned variable" var)
                 (car vals)))
            (else (scan (cdr vars) (cdr vals)))))
    (if (eq? env the-empty-environment)
        (error "Unbound variable" var)
        (let ((frame (first-frame env)))
          (scan (frame-variables frame)
                (frame-values frame)))))
  (env-loop env))

b

(define (scan-out-defines proc-body)
  (let ((define-list (filter definition? proc-body))
        (proc (filter (lambda (x) (not (definition? x)))) proc-body))
    (apply (make-lambda (map cadr define-list)
                        (append (map (lambda (x) (list 'set! (cadr x) (caddr x))) define-list)
                                proc))
           (map (lambda (x) '*assigned*) define-list))))

c

(define (make-procedure parameters body env)
  (list 'procedure parameters (scan-out-defines body) env))