parameter passing
更新日期:
主要分為兩種Evalulation first, or Evaluation when needed
Evalulation Argunment first
Call-By-Value
最common 的做法,先計算parameter 的value,然後把value copy 進function內
不會影響出面的數值
1  | #include <iostream>  | 
Call-By-Reference
把呼叫者(caller)的variable 直接在function內使用, 但叫第二個名字(Reference)
可以有side effect 出面的數值
1  | #include <iostream>  | 
Evaluation Argunment when needed
Call-By-Name
用的時侯才把parameter evaluate
在passing as parameter是產生closure (enclosing environement) 裝著evaluation所需的variable
以下add function 中的n 是call-by-name的,n 是array(index), 當中的index 是記憶著上面的index
1  | object CallByName {  | 
所以如果closure 內的variable數值被外內改變
會影響evaluation的結果1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21object CallByName {
  var array = Array(0, 1, 2, 3)
  var index = 0 
  
  def add(n: => Int) : Int = {
    index = 1; // 改變了closure 內的variable 數值
    return n;
  }
  
  def callAdd() = {
    add(array(index))
  }
  
}
defined object CallByName
scala> CallByName.callAdd
res3: Int = 1
改變local variable 是沒有作用的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19object CallByName {
  var array = Array(0, 1, 2, 3)
  var index = 0
  
  def add(n: => Int) : Int = {
    var index = 1; // 這不是closure內的variable
    return n;
  }
  
  def callAdd() = {
    add(array(index))
  }
  
}
defined object CallByName
scala> CallByName.callAdd
res2: Int = 0
Clousre in Javascript
利用javascript 達成類似call-by-name的效果
1  | function CallByName(){  | 
Call-By-Need
Call-By-Name + memorized the evaluation result, evalute argunment 後把結果儲起來
就算之後改變argunment也不會影響evaluation的結果
Call-By-Text
類似Call-By-Name ,但passing as parameter時沒有closure 裝著所需的variable
到evaluation 時才找所需的variable
個人認為javascript內的eval 是類似效果?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function CallByText(){
    var array = [0, 1, 2, 3];
    var index = 0;
    this.add = function(n){
        var index = 1;
        return eval(n);
    }
    this.callAdd = function(){
        return this.add('array[index]');
    }
}
var callByText = new CallByText();
console.log(callByText.callAdd());
