SICP 問題 4.17
lambdaを評価すると新しくフレームが作られます.
これを防ぐためにletでunassignmentを束縛するのではなくdefineで内部定義します.
define-variable!はフレームに新たな変数を追加する手続きなので余計なフレームは作られません.
scheme (define (scan-out-defines body) (define (split-def-body proc-body) (let iter ((proc-body proc-body) (def '()) (body '())) (cond ((null? proc-body) (cons (reverse def) (reverse body))) ((definition? (car proc-body)) (iter (cdr proc-body) (cons (car proc-body) def) body)) (else (iter (cdr proc-body) def (cons (car proc-body) body)))))) (let* ((def-body-list (split-def-body body)) (def-list (car def-body-list)) (body-list (cdr def-body-list))) (if (null? def-list) body (append (map (lambda (x) (make-definition (definition-variable x) ''*unassigned*)) def-list) (map (lambda (x) (list 'set! (definition-variable x) (definition-value x))) def-list) body-list))))