為什麼我們需要學習函數語言程式設計?或者說函數語言程式設計有什麼優勢?這個系列中我會用 scala 給你講述函數語言程式設計中的優勢,以及一些函式式的哲學。不懂 scala 也沒關係,scala 和 java 是類似的,在每篇的開頭我也會先說明這節中用到的 scala 語法。
為什麼函數語言程式設計這幾年火起來
如 Python 一樣,函數語言程式設計(FP,即Functional Programming)也是近幾年才逐漸為人們所知,但它並不是一個多麼新的概念。它擁有和麵向物件程式設計(OOP)幾乎等長的歷史。但縱觀每件事的脈絡,總是有原因的,函數語言程式設計這幾年變火的原因是什麼呢?
最主要的原因是摩爾定律的逐漸失效,計算機的發展道路趨向於多核 CPU 與分散式的方向。我們經常使用的物件導向程式設計的優勢在於能夠很好得對要解決的問題領域進行建模,但它在多執行緒程式設計環境下的同步阻塞呼叫,以及由此帶來的執行緒安全問題,與函數語言程式設計天然適合分散式併發程式設計的程式設計方式相比,當真相形見絀。而未來明顯是大資料的時代,故而函數語言程式設計只會越加重要,甚至未來可能是函數語言程式設計的時代。
摩爾定律:1965年,英特爾公司創始人戈登·摩爾提出,在至多10年內,積體電路的整合度會每兩年翻一番,即摩爾定律。後來這個週期被縮短到了18個月。也就是說,每隔18個月,計算機等IT產品的效能就會翻一番;或者說相同效能的計算機等IT產品,每18個月價錢會降一半。幾十年來IT行業的發展始終遵循著摩爾定律預測的速度。
什麼是函數語言程式設計
有一篇有趣的文章,或許可以讓你對函數語言程式設計有所瞭解,可以先看看它,稍後再看看對函式式的正式定義,函數語言程式設計聖經。
所謂函數語言程式設計,其實就是以純函式的方式編寫程式碼,純函式的定義如下:
純函式:一個函式在程式的執行過程中除了根據輸入引數給出運算結果之外沒用其他影響,就可以說是沒有副作用的,我們就可以將這一類函式稱之為純函式。
純函式最核心的目的是為了編寫無副作用的程式碼,它的很多特性,包括不變數,惰性求值等等都是為了這個目標。那什麼叫做無副作用呢?我們用一個例子來看看。
咖啡店購物的例子 --scala
先來看一段有副作用的程式碼:
class Cafe {
//使用者購買一杯咖啡執行的函式
def buyCoffee(Cc: CreditCard) : Coffee = {
val cup = new Coffee()
//副作用所在,除了返回一杯咖啡,它還去通知信用卡公司扣費
cc.charge(cup.price)
cup
}
}
這個函式的副作用是什麼呢?就是在購買了一杯咖啡的時候使用信用卡去計費,它會通知信用卡公司去進行一系列處理。
這樣會導致什麼問題呢?首先,副作用會讓這段程式碼變成執行緒不安全。其次,會讓這段程式碼難以測試,如果想測試這段程式碼的邏輯,就不得不每次都讓信用卡扣費。但我們只是想測試一下邏輯而已,並不想真正扣費。再者,當你想要一次購買多杯咖啡的時候怎麼辦,你只能跳腳。
這時候我們再看看函式式的方式去實現:
case class Charge(cc: CreditCard,amount: Double)
class Cafe{
def buyCoffee(cc:CreditCard) : (Coffee,Charge) = {
val cup = new Coffee()
(cup,Charge(cc,cup.price))
}
}
看到了嗎,經過我們這樣改變之後,函式變得沒有副作用了。也就是說,無論執行這個 buyCoffee 函式多少次,它只會返回給我一杯咖啡以及它的價錢,這樣我們就可以很方便得對它的邏輯進行測試而不必擔心影響到信用卡。並且它可以安全得執行在多執行緒環境下。
其實從物件導向的角度來看,這是不是有點像物件導向裡面的一些設計模式呢?這樣做解耦了咖啡和信用卡之間的關係,在後面新增其他功能的時候我們可以方便得進行組合,比如說想要有一個多杯咖啡計費的功能,如果是用上面那段程式碼來實現需求,那麼無疑會很痛苦。但通過函式式的方式改編後,一些變得清晰起來~
從這個角度來說,函數語言程式設計其實也可以是一種程式設計思維,它無法幫你立即獲得更好的職位,但卻可以從某種程度上改變你程式設計的思維,讓你寫出更優秀的程式碼。
結語
最近幾年,很多新火起來的概念,但它們其實早在上世紀就已經被髮明出來,無論時機器學習,深度學習,Python語言,還是函數語言程式設計。這是為什麼呢?這是因為這些技術的邊界發生變化,或者說這個時代的技術邊界變了。
每個時代都有每個時代的技術邊界,真正的工程師會知道邊界在哪裡,只有外行才會無法無邊。巴菲特說他不投資自己不懂的東西,正是因為他給自己的劃定了一個邊界。
蘋果公司能夠成功的一個重要原因正是因為它清楚得知道時代的邊界,並且能在邊界內做到最好。你看蘋果很多產品都具有劃時代的意義是吧,但其實那些產品都不是蘋果首創,比如智慧手機,最早是日本公司 DOCOMO 發明,個人平板電腦是英國首先發明。IPod,MP3 也是韓國先出品的。蘋果公司用的很多技術甚至在 30 年前就有了,但為什麼直到被髮明出來才為人們所知?
正是因為蘋果瞭解時代的技術邊界,並在邊界內做到最好。
往小了說,當我們在學習新的技術,或是使用新技術完成某項工作的時候,我們一定要直到它的邊界在哪裡。往大了說,我們應該像蘋果一樣,多多思考這個時代的技術邊界在哪裡,這樣才不至於陷入無休止的技術追趕之中。