函數語言程式設計應該是你2015年的最優先選擇

edithfang發表於2015-01-07
你可能聽過 "Clojure", "Scala", "Erlang" or even "Java now has lambdas"這些詞語。你也可能知道這些詞語"函數語言程式設計"有關。如果你有逛程式設計論壇,那麼這個東西,你應該經常見到。

如果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)

相關文章