作者scwg ( )
看板PLT
标题Re: [问题] 为什麽local variable的scope不能延及子程序?
时间Thu Mar 6 20:47:25 2008
趁 noctem 老师还没上线来献个丑 :p
这个议题的两种做法分别叫 static scoping 和 dynamic scoping
static 就是 C/C++ 以及目前几乎所有主流语言处理 local variable 的方式
dynamic scoping 我只知道早年的 lisp 有在用
godfat 大已经提过两者在实用上的差异
基本上 dynamic scoping 会造成「关注点」分散,
一个 function 的 local variable 会被此 function 以外的程式所更改
比起来 pass by reference 至少会把 reference 传进去,
是看得到某个变数有机会被改到的
这造成 dynamic scoping 的程式在设计与除错上非常困难
我再补充两个这两种 scoping 的差异
首先, dynamic scoping programming language 的 typing 会变得很复杂
compile 成 machine code 更难:
int main(){
a();
b();
return 0;
}
void a(){
int x = 1; // A
dynamic_scoping();
printf("%d\n", x);
}
void b(){
double x = 1.0; // B
dynamic_scoping();
printf("%f\n", x);
}
void dynamic_scoping(){
x += 2; // C
}
在 C 的地方, 请问 x 的型态是什麽?
如果是在 main() -> a() -> dynamic_scoping()
的情况下, 因为 A, x 是 int
可是在 main() -> b() -> dynamic_scoping() 的设定下就变成 B 处的 double
第二, C 这一行要如何 compile 成 machine code?
如果 x 是 int, 那就用普通的整数加法就可以了,
但是如果是 double 就要用 floating point add 去加 floating point 型式的 2.0
甚至如果 x 是 class, 有 overload += operator, 或根本不支援..
但是, 如果今天上面那个程式不是 compiling language,
而是用 interpreter 去执行的话, 事实上这样的 interpreter 是比较好实作的!
因为
1. interpreter 本来就会记得每个变数的型态, 所以上第一点就不重要了
2. 既然有 1. 只要根据变数型态很容易判断 += 该怎麽执行, 所第二点就绕过了
3. 不用 maintain stack, 只要一个 flat namespace, 或一个 hash 就够了
(虽然这样 JIT 同样变得遥不可及...)
(但是这解释了为什麽早年的 lisp 是 dynamic scoping -- interpreter 好写)
最後, 类似 interpreter, dynamic scoping language 的 semantics 比较好定义..
不论是 denotational semantics 还是 operational semantics..
(我没试过 axiomatic semantics, 所以不确定..)
--
A man may die, countries may rise and fall, but an idea lives on.
- John F. Kennedy
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.54
※ 编辑: scwg 来自: 140.112.30.54 (03/06 20:47)
1F:推 godfat:晚点我在讲讲一些 dynamic scoping 的经验... 现在在忙别的 03/06 22:49