parameters可以認爲是與形參(formal parameter)對應,在函數定義時,用來表示如何處理將來傳進來的數據,它需要類型信息。arguments是實參(acturla parameter),當函數調用時,表示傳遞進去的數據。它的類型必須與函數定義時的parameters相同,否則就是類型不匹配的錯誤。
例如:def f(x): x*x 這裏的x就是parameter,而在定義之後,調用時,a = 2;f(a),那麼a就是argument。
parameters可以看作函數的固定屬性,它們表徵了函數內部的特性,例如如何操作傳遞進來的參數,實際上起着佔位符的作用;arguments是隨着函數調用的上下文而變,在代碼運行時,佔位符將被實際參數的值取代。
這就有一個問題:如何以及何時計算argument的值?
在call by value 和call by reference方案裏,函數應用都是在進入函數體之前求arguments的值。因此,函數必須能夠查詢當前arguments的值,並通過賦值語句改變它們的值。
call by value就是在執行函數前,計算argument的值,並且把計算結果綁定到函數內的參數上,通常是在內存中重新分配空間。當函數返回後,這個空間也被收回,也就是說在上例中,a = 2; f(a); 如果在函數內部發生對a的賦值,調用函數f(a)返後,a的值是不變的,還是2。
call by refernce策略有所不同,在argument值的計算過程中,傳遞進來的不再是值,而是對它們的直接引用,也既是,如果對參數重新賦值,函數調用返回後,在caller的作用域是能看到值的變化。
def modify(var p, &q) {
p := 27 # passed by value - only the local parameter is modified
q := 27 # passed by reference - variable used in call is modified
}
? var a := 1
# value: 1
? var b := 2
# value: 2
? modify(a, &b)
? a
# value: 1
? b
# value: 27