2011-03-21 63 views
7

大多數教程/文章/書籍在介紹函數式編程時討論副作用。藉此Python代碼:函數式編程:副作用

def isPrime(n): 
    k = 2 
    while k < n: 
     if n % k == 0: 
      return False 
     k += 1 
    return True 

的文字說,上面的函數有局部副作用,我不明白這一點。我看到變量「k」正在改變,我不明白它有什麼不好。

有人可以給一個明顯的壞副作用的例子,以及如何通過函數式編程避免它嗎?

+0

W.r.t.請注意FP與程序編程[與IP與DP正交](http://stackoverflow.com/questions/602444/what-is-functional-claclarative-and-imperative-programming/8357604#8357604 )。 – 2011-12-08 01:16:19

回答

16

您提到的文本是正確的,更改局部變量被認爲是副作用。

這並不是說這是一件壞事。這只是功能編程。在純粹的函數式編程語言中,您可以用遞歸方式編寫循環,無需更改變量。

像這些寫函數(沒有可觀察的副作用)在任何語言中都是很好的練習,它不是函數式編程。

編輯:現在我看到你對「不良」副作用的評論。我不會說副作用不好。在大多數主流語言中,沒有它們就很難進行編程,我認爲很多程序員都會考慮副作用。但是在大型軟件項目中,過度依賴副作用會讓你的生活變得非常悲慘。 Here's a nice example involving singletons (the ultimate way to cause side effects)

在一種禁止副作用的語言中,作爲程序員的你和作爲編譯器的意外少。純函數代碼更易於分析和並行化,並且至少在理論上更容易被編譯器優化。

3

副作用(特別是不具有參照透明度)使result of your code depend on the order of execution of the statements。因此,改變調用某對函數調用的順序,可能會改變程序斷開區域的行爲。這是因爲它們之間並沒有真正的連接,因爲共同的副作用。

這使得程序的分解變得難以置信,從而令人沮喪地嘗試用新代碼組合現有代碼,或者隔離並分離代碼的任何部分的功能。換句話說,副作用就像Rigor Mortis膠水一樣,會滲透到所有東西上,並導致它成爲一個不可磨滅的整體式意大利細麪條。嘗試拔出一條麪條,而不會對其他麪條造成一連串的干擾。