如果Google搜尋" Functional Programming",你找不到什麼新東西。曾經第二大語言擁抱他,出現在上世紀50你年代,被命名為Lisp。那麼,為什麼現在才流行呢?
剛開始,電腦執行慢
信不信由你,以前電腦比DOM執行還慢好多。在那個時候,主要有兩種設計習慣和程式語言:
- 1、以馮·諾伊曼結構開始,並抽象化
- 2、以數學運算開始,並移除抽象化
那時候的電腦沒辦法處理抽象物件求函式程式值。因此,由於不適合工作,Lisp以慢慢死亡收場。然後,指令式程式設計開始了它的統治,特別是C的崛起。
現在,電腦效能大幅提升
現在,電腦跑大多數程式已經沒有壓力,無需在意他使用什麼語言。然後,函數語言程式設計語言重生。
函式程式語言(FP)
你可以這樣理解函數語言程式設計語言:用函式程式設計,但讓,事實上,比想象中還要更加接近字面意思。你可以使用其他函式標準建立函式,編寫函式。
這裡有一個(簡單)的FP特性列表
- First-Class Functions一級函式
- High-Order Functions高階函式
- Pure Functions純函式
- Closures閉包
- Immutable State不變狀態
你也許不會再以他的中文翻譯,但是,你會在意他們到底是什麼意思。
First-Class Functions:可以在變數中儲存函式。我想你已經做過如下面 JavaScript的內容。
varadd = function(a, b){ returna + b }
你現在正在儲存一個匿名函式,得到a,b,以及返回a+b到add變數。
High-Order Functions:函式可以返回函式,像引數一樣接收函其他數。
J
avaScript:
document.querySelector('#button') .addEventListener('click', function(){ alert('yay, i got clicked') })
或者
varadd = function(a){ returnfunction(b){ returna + b } } varadd2 = add(2) add2(3) // => 5
上面兩個例子都是High-Order Functions例子,儘管,你可能從未謝過如此程式碼,你也可能在某個地方見過這種格式。
Pure Functions:函式不改變值,值接收資料和輸出資料,和數學運算函式相似。這也意味著,如果為函式f傳遞2,並返回10,他將會返回10.跟環境、執行緒、或其他求值命令無關。在其他程式設計中也不會受影響,非常有用。
Closures:可以在使用的特殊返回函式中儲存一些資料,比如返回函式保持執行環境。
varadd = function(a){ returnfunction(b){ returna + b } } varadd2 = add(2) add2(3) // => 5
High-Order函式的第二個例子中,變數a是封閉的,只能用於返回函式。事實上,閉包並不是FP特色,只是優化。
Immutable State:無法改變任何狀態(即使可以新建也不行),在下面的例子(in OCaml),使用x和5在專案中交換。x永遠等於5。
let x = 5;; x = 6;; print_int x;; (* prints 5 *)
看起來並不是好功能,不過關鍵時候可以救命。
物件導向程式設計(OOP)再也救不了我們了
分散式、併發應用程式的時代終於來臨了。不過,我們還沒準備好:我們現在的(比如:使用的)並行模型,雖然可以解決問題,卻帶來複雜性。
得到一個更好的應用,我們需要一個更簡單、可靠的方式來實現。記得我們上面提到的幾種功能嗎?Pure Functions 和 Immutable State?誠然,你可以在不同核心或者機器上執行無數次函式,你只能得到相同的輸出結果。因此,你可以使用相同的程式碼,在1個核心上使用,也可以在1000個核心上使用。
"但是為什麼我不能繼續使用OOP ?"
函數語言程式設計
萬事開頭難。我想你學習程式設計付出了很大的努力,甚至還在學習OOP。也許,現在的你使用OOP比你剛開始學習程式設計的時候簡單多了。為什麼呢?因為你已經熟悉許多常用語了,比如變數宣告、 for/while 迴圈。
對於剛開始學習FP的人,就想是重新學習程式設計一樣(取決於你開始學習哪種語言,從哪裡開始)。
許多人說,FP可讀性不好。如果你有學習過規則的背景,函數語言程式設計看起來就像個crypt語言,並不是因為他是crypt,而是你並不熟悉那些常用語。當你掌握基礎之後,他的可讀性就增強了。
來看看下面的Haskell 和 JavaScript 程式碼:
guess 7 = "Much 7 very wow." guess x = "Ooops, try again." -- strongly inspired by http://learnyouahaskell.com
functionguess(x){ if(x == 7){ return"Much 7 very wow." } else{ return"Oops, try again." } }
這是一個很簡單的程式。當你正確輸入7後會輸出一個賀詞,不然會輸出錯誤資訊提示。
Haskell可以使用2行程式碼完成是怎樣做到的(忽略第一行)。如果你理解了Pattern Matching(匹配模式),這個問題就非常簡單了。
Haskell 做了些什麼:
如果函式接收內容等於7,他返回"Much 7 very wow",否在返回"Ooops, try again."。
這就是JavaScript程式碼做的事情,Haskell匹配程式設計者提供的"模式"。
plus1 :: [Int] -> [Int] plus1 [] = [] plus1 (x:xs) = x + 1 : plus1 xs -- plus1 [0,1,2,3] -- > [1,2,3,4]
在上面的程式中,plus1是一個得到Ints列表的函式。為每個元素新增1。與空List []匹配(沒有其他匹配,返回另一個空列表)。通過定義模式來確認非空列表:為列表中第一個元素命名為x,剩下的為xs。然後用求和和遞迴呼叫返回。
我可以肯定,你在使用這兩行Imperative Style程式碼重寫 plus1 的時候胡出現錯誤。不過他依舊有可讀性。
那麼,新的一年,Functional Programming ,讓我們從現在開始吧!
來自:慧都控制元件網
相關閱讀
評論(2)