1. 程式人生 > >函數語言程式設計(functional programming)學習總結

函數語言程式設計(functional programming)學習總結

梳理一下函數語言程式設計中的各個概念,會不定期更新。大部分是轉載別人的文章,加一些感想,所以也不能算作原創。

lambda演算與currying

下面這篇文章講得很清楚:

lambda演算定義了一些和函式相關的操作,包括把函式當做引數、把函式當做返回值。currying則是指把一個帶有n個引數的函式轉化成n個單引數的函式鏈,通過只給部分引數賦值,進而引出partial function的概念。在scala等語言裡面是直接支援currying的,python有相應的庫functools.partial來支援。

Monad

Monad這個東西不好翻譯也不好解釋。知乎上有一個很好的討論:

其中有一條建議是:初學者不要隨便寫monad tutorial。。。誤人子弟。。於是我就不敢多說了,不準確的講,monad就是將一系列的操作序列給封裝起來了。

非同步程式設計(Asynchronous Programming)

對於大部分從C/C++走過來的人來說,非同步程式設計是一個不大好掌握的東西。因為我們總是習慣於上一條語句執行完了再開始執行下一條,但是aynchronous就常常以為這上條語句的結果還沒出來,下條語句就開始執行了。

非同步程式設計常常和event based programming沾上邊,比如網頁中client和server的互動,發出http請求之後,不可能一直阻塞在那裡等待響應返回或者超時事件發生,那樣執行效率太低。

我接觸的和非同步程式設計的程式語言主要是node.js和scala,推薦兩篇文章:

1.介紹scala中的future、promise等非同步特性:

2.介紹node.js中的非同步相關:

3.scala當中的actor,可以把actor理解成更細粒度的thread。

要想深入瞭解,可以自己多去搜索資料。

java 8中新增的FP特色

lambda表示式、Function介面

java常被詬病的一點就是寫出來的程式碼一大坨。。但其實就幹了那麼一點事情。。lambda表示式的引入可以大大簡化java程式碼,比如sort函式,不需要自己寫一個Comparator介面,直接傳入一個lambda表示式就行了。

方法引用(Method Reference)

在需要傳遞一個函式作為引數的地方,除了可以傳入一個lambda表示式之外,也可以傳遞一個現成的方法。

流(stream)

流就是一個無窮長的序列,infinite sequence,當然了,記憶體有限的計算機無論如何都不可能儲存得下無窮長度的序列。因此stream常常和lazy evaluation(惰性求值)關聯在一起,只有在實際需要求值的時候才會把流中的值求出來。

基於stream的操作往往強大而且簡潔,常見的有map, filter, reduce,在python裡面這些都是內建的函式,在其他程式語言中一般也有實現。

Optional類

java裡面很煩人的一個異常就是NullPointerException,新引入的Optional類就是為了減少程式設計者處理NullPointerException的麻煩。Optional,顧名思義,就是這個類裡面可能有資料,也可能沒有。

在C++的boost庫裡面,也有一個類似的boost::optional:

並行陣列(Parallel Array)

在現代的處理器上,一般都是multiple core的,但是以前庫函式裡面的sort等演算法都是序列的實現,為了充分開發並行性,java 8引入了parallel array.

在資料量小的時候,併發去做一般得不償失,但資料量很大的情況下往往可以獲得幾倍的加速。

總結

FP是個很神奇的東西,還需要不斷學習和實踐。。。