Reasoned Schemer (55) 10章 walk*
(walk w ``((,x . b) (,z . ,y) (,w . (,x e ,z))))
は``(,x e ,z)
だけど
(walk* w ``((,x . b) (,z . ,y) (,w . (,x e ,z))))
は``(b e ,y)
になる
そんなwalk*
について考える
変数が見つかったら終わりというだけではなくて
値の中に変数があればそれも置き換えていくってことでしょう
比較のためwalk
再掲
(define (walk v s)
(let ((a (and (var? v) (assv v s))))
(cond
((pair? a) (walk (cdr a) s))
(else v))))
これがwalk*
(define (walk* v s)
(let ((v (walk v s)))
(cond
((var? v) v)
((pair? v) (cons (walk* (car v) s) (walk* (cdr v) s)))
(else v))))
まずwalk
する
walk
した結果がpairでなければそのまま返す
pairだったらcarとcdrを再帰的にwalk*
する
(てことは((var? v) v)
はお飾り?)
もうすこしかみ砕いていうと
walk
した結果がリストだったらその各要素についてまたwalk*
する
すべての変数についていけるところまでwalk
しつくすから
最終的な結果に変数が残ってたらそれはfreshということ