## 函數式編程
[函數式編程](http://en.wikipedia.org/wiki/Functional_programming) 是一種強調函數必須被當成第一等公民對待, 并且這些函數是“純”的編程方式。這是受 [lambda表達式](http://en.wikipedia.org/wiki/Lambda_calculus) 啟發的。純函數的意思是同一個函數對于同樣同樣的參數,它的返回值始終是一樣的 — 而不會因為前一次調用修改了某個全局變量而使得后面的調用和前面調用的結果不一樣。這使得這種程序十分容易理解、調試、測試。它們沒有副作用 — 修改某些全局變量, 進行一些IO操作(文件IO和數據庫)。狀態被維護在方法的參數上面, 而這些參數被存放在棧(stack)上面(通常通過遞歸調用), 而不是被維護在全局的堆(heap)上面。這使得方面可以被執行多次而不用擔心它會更改什么全局的狀態(這是非常重要的特征,等我們討論事務的時候你就會意識到了)。這也使得高級編譯器為了提高代碼性能而對代碼進行重排(reording)和并行化(parallelizing)成為可能。(并行化代碼現在還很少見)
在實際生活中,我們的程序是需要一定的副作用的。Haskel的主力開發Simon Peyton-Jones曾經曰過:
“到最后,任何程序都需要修改狀態,一個沒有副作用的程序對我們來說只是一個黑盒, 你唯一可以感覺到的是:這個黑盒在變熱。。”( [http://oscon.blip.tv/file/324976](http://oscon.blip.tv/file/324976) )
問題的關鍵是我們要控制副作用的范圍, 清晰地定位它們,避免這種副作用在代碼里面到處都是。
把函數當作“第一公民”的語言可以把函數賦值給一個變量,作為參數來調用別的函數, 同時一個函數也可以返回一個函數。可以把函數作為返回值的能力使得我們選擇之后程序的行為。接受函數作為參數的函數我們稱為“高階函數”。從某個方面來說,高階函數的行為是由傳進來的函數來配置的,這個函數可以被執行任意次,也可以從不執行。
函數式語言里面的數據是不可修改的。這使得多個線程可以在不用鎖的情況下并發地訪問這個數據。因為數據不會改變,所以根本不需要上鎖。隨著多核處理器的越發流行,函數式語言對并發語言的簡化可能是它最大的優點。如果所有這些聽起來對你來說很有吸引力而且你準備來學學函數式語言,那么你要有點心理準備。許多人覺得函數式語言并不比面向對象的語言難,它們只是風格不同罷了。而花些時間學了函數式語言之后可以得到上面說到的那些好處,我想還是值得的。比較流行的函數式語言有: [Clojure](http://clojure.org/) , [Common Lisp](http://en.wikipedia.org/wiki/Common_Lisp) , [Erlang](http://erlang.org/) , [F#](http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/default.aspx) , [Haskell](http://www.haskell.org/) , [ML](http://en.wikipedia.org/wiki/ML_(programming_language)) , [OCaml](http://caml.inria.fr/ocaml/index.en.html) , [Scheme](http://en.wikipedia.org/wiki/Scheme_(programming_language)) , [Scala](http://www.scala-lang.org/) . Clojure和Scala是Java Virtual Machine (JVM)上的語言. 還有一些其它基于JVM的語言: [Armed Bear Common Lisp (ABCL)](http://common-lisp.net/project/armedbear/) , [OCaml-Java](http://ocamljava.x9c.fr/) and [Kawa (Scheme).](http://www.gnu.org/software/kawa/)