什么是静态作用域和动态作用域呢?
举个例子:
(let ([x 2])
(let ([f (lambda (y) (* x y))])
(let ([x 4])
(f 3))))
如果是静态,结果是6,动态结果是12.
首先要明确一个概念叫自由变量,比如在函数f :(lambda (y) (* x y))中x就是自由变量
所谓静态,动态作用域,无谓是自由变量x的取值问题
还要知道一个概念叫闭包:其实可以理解为一个数据结构
(struct Closure (f env))
这个数据结构中有函数体和所谓的环境env(其实也就是continuation)
要想知道为什么是这样的结果,可以直接看解释器的代码(来源于王垠的代码)
静态作用域:
(Closure `(lambda (,x) ,e) env-save)
(interp e (ext-env x v2 env-save)))
看不懂没关系,第一行就是在函数f的闭包中把之前保存的env取出来并赋给env-save(据代码可知f的env为 (x 2))
第二行就是解析 函数体e,在一个新环境下。(这个新环境就是在env-save中加上关于形式参数的绑定形成的,简而言之就是在(x 2)的基础上加上(y 3),所以新环境就是((y 3)(x 2)))。顺序很重要在查找变量时会返回第一个值,所谓解析函数体e就是在新环境下执行函数体e(* x y)
自然结果是6
动态作用域:
(interp e (ext-env x v2 env))
在动态作用域下根本没有闭包这回事,直接在现在的env下执行函数体e。而在现在的env下x是4,所以结果是12
参考资料
1.怎样写一个解释器(怎样写一个解释器 (yinwang.org))