作者Favonia (小西风最乖了*^^*)
看板PLT
标题Re: [问题] 想请问一个关於"参数传递"的问题
时间Thu Jan 5 08:11:40 2012
个人觉得程式语言理论在台湾相当不盛行,当然也
不用太期待预官考试能多符合理论。我这篇主要想讲的
是 call-by-reference 在理论上可能的解读方法。
我认为一般 strict 语意下之所以还要分 call-by
reference 和 call-by-value, 实际上是因为程式语言
在很多情况下结合(或搞混)了参照(reference)和
参照指到的值。举例来说这段 C:
| int x = 0;
先不考虑什麽没初始化的问题,严格来说 x 不像
int, 而像一个指到某个存放 int 的地方的参照。参照
本身也是一个值;在 C 中,某种程度上可以透过取址
运算得到参照本身,或是在 C++ 中,可以有
| int &x = y;
来把 y 的值(是参照!)丢给 x. 很多语言中写
"x" 同时代表 x 这个参照和 x 这个参照指到的值。例
如 C 这一行:
| x = x + 3;
左边的 x 取的是参照的意思,右边取的是它的值。
在这些语言中可能要靠类似 non-const lvalue 的概念
来理解。追根究底是因为程式语言自己先把两个概念混
在一起了。在传递参数时,也由於同样原因,需要发明
两种传递方法(区分原本混在一起的概念);姑且称作
call-by-value 和 call-by-reference. 我认为如果一
开始没有混在一起,其实只要 call-by-value 就够了。
我学过的少数程式语言中,只有 (Standard) ML,
Haskell 和 Algol 68(G) 有清楚区分两者。例如在 ML
中上面的程式码写法是
| let
| val x = ref 0
| in
| x := !x + 3
| end
需要特别写清楚惊叹号,而且 x 的型态是 int ref
不是 int. Haskell 中对应的是 IORef Int. Algol 68
中如果写
| INT x := 0
实际上是下面这行的缩写
| REF INT x = LOC INT := 0
非常清楚的指出 x 其实是个参照。不过 Algol 68
在很多状况下允许参照自动转成参照指到的值(类似上
面 !x 的惊叹号不用写)。这点就理论上来说,就稍微
比较不严谨一点。
顺带一题,许多人说函式语言里面的变数不能改,
其他一般语言的变数可以改,我觉得跟理论有点距离。
我认为比较符合理论的讲法是,所有语言的变数都不能
改,只是很多语言的变数其实都是参照而不是指到的值
本身;在很多语言中,参照本身是不能改的,所谓的
「可以改」是指改了参照指到的值。一些函式语言的参
照指到的值也可以换掉,只是强迫你写下之前偷懒没写
的东西罢了。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.39
※ 编辑: Favonia 来自: 140.112.30.39 (01/05 08:23)
1F:推 godfat:抱歉现在才细看。我觉得这说法还满好的,之前不知道 ML 01/13 04:52
2F:→ godfat:可以用这种写法... @@ 01/13 04:52
3F:→ Favonia:Haskell 因为要 "pure" 所以写起来长了一点 xD 01/13 08:46
4F:推 ofspring:感谢你的说明 <(_ _)> 01/19 00:41