call-by-name 被定義為 Name Replacement:「參數列中的每個參數,如果未指定以
傳值的方式來傳遞,就必須以實際傳入的參數來取代。」在 Compilers - Principles,
Techniques, and Tools 這本書的 7.5 節中,它被解釋為 inline-expansion。其原因
是,以 call-by-name 的方式呼叫函式時,如果在某個參數位置上指定了一個運算式
(expression) 當作參數,那麼這個 expression 會被直接傳入函式裡面進行展開,所以,
這個 expression 是在函式裡面才進行運算的,而不是在參數列中預先計算好它的值再傳
進去。這就產生了 delayed evaluation (延遲計算) 的效果。delayed evaluation 的好處
是,只有當函式需要某個 expression 參數的值,該 expression 才會被計算,否則就不
用了。call-by-name 比較顯著的例子是 swap 函式,swap 通常是這樣寫的:
proc swap(A, B) {
tmp = A;
A = B;
B = tmp;
}
proc main() {
i = 2;
a[3] = {5, 6, 7};
swap(i, a[i]);
}
swap 的實際工作情形是:
swap(i, a[i]) { // i is 2
tmp = i; // tmp becomes 2, since i is 2
i = a[i]; // i becomes 7, since a[2] is 7
a[i] = i; // inline expansion of B, delayed evaluation ==> a[7] = 7
}
在 P(X, Y, Z) 這個例子中:
proc P(X, Y, Z) {
Y = Y + 1;
Z = Z + X;
}
P(a+b, a, a) { // a = 2, b = 3
a = a + 1; // a becomes 3
a = a + (a+b); // inline expansion of X, a becomes 9
}
沒有留言:
張貼留言