python學習 函數式編程

一.定義:"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程序的方法論。

我們常見的編程範式有:命令式編程(Imperative programming)函數式編程邏輯式編程,常見的面向對象編程是也是一種命令式編程。
命令式編程是面向計算機硬件的抽象,有變量(對應着存儲單元),賦值語句(獲取,存儲指令),表達式(內存引用和算術運算)和控制語句(跳轉指令),一句話概括命令式程序就是一個馮諾依曼機指令序列而函數式編程是面向數學的抽象,將計算描述爲一種表達式求值,一句話概括,函數式程序就是一個表達式

二.特點

1. 函數是"第一等公民"

指的是函數與其他數據類型一樣,處於平等地位,可以賦值給其他變量,也可以作爲參數,傳入另一個函數,或者作爲別的函數的返回值。

而高階函數就是參數爲函數或返回值爲函數的函數。有了高階函數,就可以將複用的粒度降低到函數級別,相對於面嚮對象語言,複用的粒度更低。

Pyhton的高級函數,如代碼所示:

def add(x , y , f):
    return f(x) + f(y)

print add(-5 , 6 , abs)

把函數abs作爲另一個函數add的參數傳入,那麼函數add稱爲高階函數,函數式編程就是指這種高度抽象的編程範式。

2. 只用"表達式",不用"語句"

"表達式"(expression)是一個單純的運算過程,總是有返回值;"語句"(statement)是執行某種操作,沒有返回值。函數式編程要求,只使用表達式,不使用語句。也就是說,每一步都是單純的運算,而且都有返回值。

原因是函數式編程的開發動機,一開始就是爲了處理運算(computation),不考慮系統的讀寫(I/O)。"語句"屬於對系統的讀寫操作,所以就被排斥在外。

當然,實際應用中,不做I/O是不可能的。因此,編程過程中,函數式編程只要求把I/O限制到最小,不要有不必要的讀寫行爲,保持計算過程的單純性。

3. 沒有"副作用"

指的是函數內部與外部互動(最典型的情況,就是修改全局變量的值),產生運算以外的其他結果。

函數式編程強調沒有"副作用",意味着函數要保持獨立,所有功能就是返回一個新的值,沒有其他行爲,尤其是不得修改外部變量的值。

4. 不修改狀態

上一點已經提到,函數式編程只是返回新的值,不修改系統變量。因此,不修改變量,也是它的一個重要特點。

在其他類型的語言中,變量往往用來保存"狀態"(state)。不修改變量,意味着狀態不能保存在變量中。函數式編程使用參數保存狀態,最好的例子就是遞歸。

5. 引用透明

引用透明(Referential transparency),指的是函數的運行不依賴於外部變量或"狀態",只依賴於輸入的參數,任何時候只要參數相同,引用函數所得到的返回值總是相同的。

有了前面的第三點和第四點,這點是很顯然的。其他類型的語言,函數的返回值往往與系統狀態有關,不同的狀態之下,返回值是不一樣的。這就叫"引用不透明",很不利於觀察和理解程序的行爲。


三、意義

1. 代碼簡潔,開發快速

函數式編程大量使用函數,減少了代碼的重複,因此程序比較短,開發速度較快。

2. 接近自然語言,易於理解

函數式編程的自由度很高,可以寫出很接近自然語言的代碼。

3. 更方便的代碼管理

函數式編程不依賴、也不會改變外界的狀態,只要給定輸入參數,返回的結果必定相同。因此,每一個函數都可以被看做獨立單元,很有利於進行單元測試(unit testing)和除錯(debugging),以及模塊化組合。

4. 易於"併發編程"

函數式編程不需要考慮"死鎖"(deadlock),因爲它不修改變量,所以根本不存在"鎖"線程的問題。不必擔心一個線程的數據,被另一個線程修改,所以可以很放心地把工作分攤到多個線程,部署"併發編程"(concurrency)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章