SICP 読み (166) 4.1.6 内部定義
色々検討してますが問題 4.16 の c についてはまだ分からん状態。とりあえず、scan-out-defines がでっち上がった。ほぼ一発だった。びっくり。
以下の試験にパスしてます。
("4.16" ("scan-out-defines" (let ((l1 '((define (even? n) (if (= n 0) true (odd? (- n 1)))) (define (odd? n) (if (= n 0) false (even? (- n 1)))) (even? x))) (l2 '(let ((even? '*unassigned*) (odd? '*unassigned*)) (set! even? (lambda (n) (if (= n 0) true (odd? (- n 1))))) (set! odd? (lambda (n) (if (= n 0) false (even? (- n 1))))) (even? x)))) (assert-equal l2 (scan-out-defines l1))) ) )
実装が以下。
(define (scan-out-defines exp) (define (make-set exp) (let f ((init '()) (set '()) (exp exp)) (cond ((null? exp) (append (list 'let init) set)) (else (cond ((definition? (car exp)) (f (append init (list (list (definition-variable (car exp)) ''*unassigned*))) (append set (list (list 'set! (definition-variable (car exp)) (definition-value (car exp))))) (cdr exp))) (else (f init set (cdr exp)))))))) (append (make-set exp) (let f ((l '()) (exp exp)) (cond ((null? exp) l) ((definition? (car exp)) (f l (cdr exp))) (else (f (append l (list (car exp))) (cdr exp)))))))
scan-out-defines はまだ修正の余地があるものと思われます (試験も十分ではないし) が、とりあえずメモ代わりに残しておかせて下さひ。(何処
しかし、この手続きに何らかのヒントがあったりするのかな、とも思ったんですが未だに c なソレが微妙なあたりが弱いな。