你必須謹守FP(函數編程)的作法,才能達到前二回文章所提到的好處。不只是你的程式要遵守FP,連你用到的程式庫也必須遵守FP。因此,利用F#進行.NET編程能否具有這些優點,我持否定的態度。畢竟.NET Framework是OOP(物件導向編程)+ Imperative Programming(命令式編程)的方式所設計出來的API(Application Programming Interface,應用程序介面),而不是依據FP的構想而設計的API。

某些營養學家認為,想靠喝牛奶獲取鐵質,是錯誤的觀念,因為鈣與鐵會互相抑制彼此的吸收。F#結合了OCaml和.NET,試圖連結雙方的優點,但結局就好比同時添加高鐵和高鈣的奶粉,實際效果可能事與願違。但F#也並非一無是處,微軟為F#特別做出一套逼近OCaml 3.06的ML相容程式庫。寫程式時盡量多使用此ML程式庫以及F#的程式庫,少用標準的.NET框架,就比較能享有FP的優點。例如:使用ParallelFX,而不要用.NET Threading API。

你可能會問:既然如此,為何不直接用OCaml就好了?因為F#是微軟的語言,以微軟豐富的資源,如果有意好好發展F#,未來的F#程式庫勢必會越來越完備,有機會能夠超越OCaml。

到底FP有哪些常見的特色?我們可以透過FP作了些什麼,來了解FP是什麼。

Higher-Order Functions:某函數如果可以接受函數當作參數,或者以函數為傳出值,我們就稱這樣的函數為「較高次方函數」(Higher-Order Function)。較高次方函數讓程式可以變得相當有彈性,而且寫法比OOP更精簡許多。函數式語言有相當大的威力來自較高次方函數,特別是函數式語言的程式庫往往會有許多較高次方函數,可以幫助你進行資料處理(例如特殊排序法、資料對應、資料過濾)、事件處理。

Currying:程式庫往往將函數定義得比較一般化,具有通用性。這樣的函數,需要傳入比較多的參數。利用Currying的方式,可以定義出「特殊化」的函數,特殊化函數將函數的局部參數先指定好,只剩下一部分參數沒有指定。例如,程式庫有個函數為power(x, y),會計算出x的y次方,那麼我們可用很簡單的語法,定義一個平方函數square(x),事先將參數y指定為2;且定義立方函數cubic(x),事先將參數y指定為3。當然非函數式語言也做得到這一點,但不可能像函數式語言的語法這麼精簡。

Lazy Evaluation:表示式的執行,可以拖延到真正需要執行時才執行,這就是Lazy Evaluation。可以讓編譯器有最大的優化空間(可以調整敘述的先後次序)、執行時符合當時最新的狀況、方便做出更高階的抽象結構,並定義無窮大的資料結構。

Continuations:利用Continuation,可以將一個函數的傳出值,傳進另一個函數當作傳入值,也可以產生循序執行的效果。利用Continuation的方式,可以讓原本沒有狀態的技術,有了狀態,讓應用程式更好寫。利用Web原本是無狀態的,如果將Continuation用到Web的開發上,會使得開發變得容易許多。

Pattern Matching:模式比對的方式,可以讓系統自動幫我們進行分支(Branch)與變數的指定(Assignment)。有了模式比對,FP可以降低依賴(Imperative語言的)switch/case與(物件導向語言的)多型,而且寫出來的程式碼也不會像switch/case那樣地巨大。

Closure:能讓函數在離開之後,其context依然保留(而不會像call stack內的frame一樣,被丟棄)。有了Closure,就可以設計「傳出值是函數」的函數。

List Processing:FP的始祖語言LISP,其名稱的意思正是List Processing,目的是要進行方便的List處理(List是資料的集合)。許多函數式語言都有好用的List處理語法(例如List Comprehensions、取出List頭部元素、插入List頭部)與Lisp處理函數(例如map、filter)。

Meta-Programming:許多FP語言都提供方便的Meta-Programming工具,讓你可以設計自己的DSL(Domain-Specific Language),來輔助軟體開發。

不過,並非所有函數式語言都具有上述的特色。許多函數編程語言都混合相當多的Imperative特性,學習函數編程時,如果使用這些語言,可能比較無法體會函數編程的意義。我鼓勵大家學習Erlang、Haskell、Occam、Oz等比較正統的函數式語言,並多多使用它們的程式庫,這可以讓你對FP有比較深刻的體驗。(全文完)

作者簡介:
蔡學鏞-技術顧問
清華大學資訊工程碩士,曾任華碩集團軟體工程師、元智大學資訊系講師、美商歐萊禮出版社技術編輯、臺灣微軟特約專欄作家。

相關連結:
思考函數編程(1)函數編程的歷史典故
思考函數編程(2)好用、又無副作用的函數編程

熱門新聞

Advertisement