Deferred Substitution 在執行出現with時,利用“substitution”,每次with的出現,它都繞著整個body置換。這一方式是由F1WAE到env再到list of FunDef為止,然後再到substitution列表中,以env的形式進行。 In Case of W ...
Deferred Substitution
在執行出現with時,利用“substitution”,每次with的出現,它都繞著整個body置換。這一方式是由F1WAE到env再到list-of-FunDef為止,然後再到substitution列表中,以env的形式進行。
In Case of WAE
DefrdSub
(define-type DefrdSub
[mtSub]
[aSub (name symbol?)
(value number?)
(rest DefrdSub?)])
lookup : symbol DefrdSub -> number
(define (lookup name ds)
(type-case DefrdSub ds
[mtSub () (error 'lookup "free variable")]
[aSub (x val rest) (if (symbol=? x name)
val
(lookup name rest))]))
interp : WAE -> number 換成 WAE DefrdSub -> number
(define (interp wae ds)
(type-case WAE wae
[num (n) n]
[add (l r) (+ (interp l ds) (interp r ds))]
[sub (l r) (- (interp l ds) (interp r ds))]
[with (x i b) (interp b (aSub x (interp i ds) ds))]
[id (s) (lookup s ds)]))
In Case of F1WAE
不經思考,會造成如下後果:
{deffun {f x} {+ y x}}
(interp (parse '{with {y 2} {f 10}})), env:[]
->(interp (parse '{f 10})), env:[y=2]
->(interp (parse '{+ y x})), env:[x=10 y=2]
->12 wrong!
更準確地說,這是static scope不適合的體現。
interp : F1WAE list-of-FunDef DefrdSub -> number
(define (interp f1wae fundefs ds)
(type-case F1WAE f1wae
...
[app (ftn arg)
(local [(define a-fundef (lookup-fundef ftn fundefs))])
(interp (fundef-body a-fundef)
fundefs
(aSub (fundef-arg-name a-fundef)
(interp arg fundefs ds)
(mtSub)))]))
在進行“function call”時,將DefrdSub重新裝入env,使其成為“arg substitution”。(local設計)