lexical綁定與dynamic綁定
EOPL 的練習題 3.28 與 3.29 中用到了dynamic綁定,運行的結果與lexical綁定中的不同,并且難與理解程序
習題 3.8 代碼
let a = 3
in let p = proc (x) -(x,a)
in let a=5
in -(a,(p 2))
習題 3.9 代碼
let a = 3
in let p = proc (z) a
in let f = proc (x) (p 0)
in let a = 5
in (f 2)
lexical binding 結果
(struct:num-val 6)
(struct:num-val 3)
dynamic binding結果
(struct:num-val 8)
(struct:num-val 5)
解析器中的代碼差異
lexical 中的 不同這處在于
(proc-exp (iden exp1)
(let ((free-var (remove-same-element (free-variables exp1 iden))))
(let ((f-env (filter-env free-var env)))
(proc-val (procedure iden exp1 f-env ))))) ;; 綁定環境變量
(call-exp (exp1 exp2)
(letrec ((proc (expval->proc (value-of exp1 env)))
(more-param (lambda (parms rsl)
(if (null? parms)
rsl
(let ((val (value-of (car parms) env)))
(more-param (cdr parms) (cons val rsl)))))))
(let ((param-lst (more-param (reverse exp2) '())))
(apply-procedure proc param-lst))))
dynamic binding 中的不同之處
(proc-exp (iden exp1)
(proc-val (procedure iden exp1 (empty-env) ))) ;; 不進行環境變量的綁定
(call-exp (exp1 exp2)
(letrec ((p-proc (expval->proc (value-of exp1 env)))
(more-param (lambda (parms rsl)
(if (null? parms)
rsl
(let ((val (value-of (car parms) env)))
(more-param (cdr parms) (cons val rsl)))))))
(let ((param-lst (more-param (reverse exp2) '())))
(cases proc p-proc
(procedure (p-var p-body p-env)
(apply-procedure (procedure p-var p-body env) param-lst)))))) ;;綁定環境變量
不同之處
在于procedure綁定環境變量env的時間不同
在lexical中是在對procedure解析的時候綁定的
而在dynamic是在運行里對env進行綁定的。
dynamic綁定的問題也是很明顯的,對于動態綁字的變量,在不同的環境上運行會得到不同的結果,認為很迷惑。