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绑定的问题也是很明显的,对于动态绑字的变量,在不同的环境上运行会得到不同的结果,认为很迷惑。