函數的副作用
轉自http://www.cnblogs.com/snandy/archive/2011/08/14/2137898.html
函數副作用 指當調用函數時,除了返回函數值之外,還對主調用函數產生附加的影響。例如修改全域變數(函數外的變數)或修改參數。
函數副作用會給程式設計帶來不必要的麻煩,給程式帶來十分難以尋找的錯誤,並且降低程式的可讀性。嚴格的函數式語言要求函數必須無副作用。
函數的副作用相關的幾個概念, Pure Function、 Impure Function、 Referential Transparent。
純函數 ( Pure Function )
輸入輸出資料流全是顯式(Explicit)的。 顯式(Explicit)的意思是,函數與外界交換資料只有一個唯一渠道——參數和傳回值。函數從函數外部接受的所有輸入資訊都通過參數傳遞到該函數內部。函數輸出到函數外部的所有資訊都通過傳回值傳遞到該函數外部。
非純函數 ( Impure Function )
與之相反。 隱式(Implicit)的意思是,函數通過參數和傳回值以外的渠道,和外界進行資料交換。比如讀取/修改全域變數,都叫作以隱式的方式和外界進行資料交換。
引用透明 ( Referential Transparent )
引用透明的概念與函數的副作用相關,且受其影響。 如果程式中兩個相同值得運算式能在該程式的任何地方互相替換,而不影響程式的動作,那麼該程式就具有引用透明性。它的優點是比非引用透明的語言的語義更容易理解,不那麼晦澀。純函數式語言沒有變數,所以它們都具有引用透明性。
以下樣本說明了引用透明與函數副作用的結合 ?
| 1 2 3 |
result1 = (fun(a) + b) / (fun(a) -c); temp = fun(a); result2 = (temp + b) / (temp -c); |
如果函數沒有副作用,那麼result1和result2將是等價的。然而如果fun有副作用,比如讓b或c加1,那麼result1和result2將不相等。因此,副作用違背了引用透明性。