作者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