2015/12/25
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))))