PLAI那些事04 Deferred Substitution

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设计)
原文地址:https://www.cnblogs.com/lastk/p/12838602.html