函數語言程式設計的優與劣
本文由碼農網 – 孫騰浩原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
如今函數語言程式設計越來越流行。越來越多的程式語言支援函式式程式設計風格,人們學習如何使用它們。函數語言程式設計已不像以前那麼小眾——現在Ruby,Java和JavaScript都使用了函數語言程式設計思想。
這些語言都有函式式的特性,但不是函式式語言。我的經驗之談,函式式語言,如Erlang或ML擁有其他主流語言缺少的特性,能讓程式設計更加安全的特性。其中之一便是使用遞迴和引數模式匹配(argument pattern matching)控制迴圈。你也可以將這些設計用於流控制( flow control)。另一個便是認真對待常量賦值。我這裡提到常量賦值因為在這些語言中,一旦你給變數繫結一個值,直到離開作用域前會一直繫結。這個特性帶來的弊端就是學習如何使用它們開發軟體很困難。對於我們這些用強型別語言的開發者,尤其困難。
遞迴和模式匹配
函數語言程式設計語言特性是執行期優化遞迴。使用尾呼叫優化,執行期提供高效的回撥環境,使每個回撥用相同的棧幀(stack frame)。再加上引數模式匹配,你可以像寫歸納法證明(高中數學的歸納法)那樣寫表示式函式。你有一個基礎步驟和歸納步驟。基礎步驟結束遞迴,歸納步驟重複遞迴。通過這種方式,你可以定義函式處理列表或集合。函式的每個變數在每次呼叫中繫結,這使得變數繫結更易於管理。下面是個虛擬碼例子:
looper(_) := return 0 looper(h, t) := return t + looper(h)
這裡,我們定義了一個函式looper()對列表內容求和。
第一個步驟是基礎步驟——如果列表為空,我們返回0。第二個步驟是歸納步驟——如果列表有頭元素和尾元素,然後我們把尾元素通過遞迴呼叫looper()方法求和。如果列表中只剩一個元素,這個元素繫結到變數t,遞迴呼叫匹配基礎步驟(因為變數h為空),然後遞迴展開。
在函式式語言中,尾呼叫優化確保了棧幀重複使用,所以本質上結構和for、while迴圈一樣,比如C語言。
如果你在Ruby或JavaScript中使用它,你必須確保在使用函式迴圈列表前尾遞迴優化是可用的。如果沒有,你將在遞迴中遇到效能問題。你在Ruby或JavaScript中只需要把基礎步驟放在歸納步驟前面就行。
常量賦值
這點在函式式語言中很難實現。畢竟用不可變的值表示可變的狀態非常困難。你又該怎麼辦呢?
記住,變數賦值只在當前作用域有效。所以你如何應對這種情況?你讓作用域很小,只在函式呼叫時繫結必須的變數。你不能編寫修改狀態的程式碼,比如在一系列迴圈中。你只能在函式呼叫時繫結狀態,然後遞迴。通過這種方式,你可以維護狀態改變,在繫結狀態變數值時很難出現錯誤。
不要使用全域性變數。它會跑到作用域外。
相比那些所謂擁有函數語言程式設計的語言,這就是你將在真正函式式語言中看到的兩點關鍵不同點。函式式程式設計讓你的重用能力更上一層樓,使程式碼更清晰,不過在沒有優化的執行環境中會有潛在的效能代價。
譯文連結:http://www.codeceo.com/article/functional-programming.html
英文原文:Functional Programming: The Good and the Bad
翻譯作者:碼農網 – 孫騰浩
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- iOS 與 函數語言程式設計iOS函數程式設計
- Scala函式與函數語言程式設計函式函數程式設計
- 函數語言程式設計函數程式設計
- Scala 函數語言程式設計(一) 什麼是函數語言程式設計?函數程式設計
- 函數語言程式設計與RxJava(附demo)函數程式設計RxJava
- RAC的函數語言程式設計函數程式設計
- javascript函數語言程式設計: 優雅的使用underscore進行函式程式設計JavaScript函數程式設計函式
- 函數語言程式設計,真香函數程式設計
- Java 函數語言程式設計Java函數程式設計
- javascript函數語言程式設計JavaScript函數程式設計
- 初探函數語言程式設計函數程式設計
- 函數語言程式設計初探函數程式設計
- JavaScript 函數語言程式設計JavaScript函數程式設計
- 優化函數語言程式設計:向PHP移植Clojure函式優化函數程式設計PHP函式
- 淺談函數語言程式設計與 Java Stream函數程式設計Java
- JavaScript中的函數語言程式設計JavaScript函數程式設計
- C++的函數語言程式設計C++函數程式設計
- python的函數語言程式設計Python函數程式設計
- JavaScript 中的函數語言程式設計JavaScript函數程式設計
- Kotlin 函式與函數語言程式設計淺析Kotlin函式函數程式設計
- 函數語言程式設計雜談函數程式設計
- 初見函數語言程式設計函數程式設計
- JavaScript 函數語言程式設計(二)JavaScript函數程式設計
- 函數語言程式設計前菜函數程式設計
- JavaScript 函數語言程式設計(一)JavaScript函數程式設計
- JavaScript 函數語言程式設計(三)JavaScript函數程式設計
- python函數語言程式設計Python函數程式設計
- JavaScript函數語言程式設計(二)JavaScript函數程式設計
- JavaScript函數語言程式設計(一)JavaScript函數程式設計
- JavaScript函數語言程式設計(三)JavaScript函數程式設計
- 函數語言程式設計初探一函數程式設計
- 函數語言程式設計簡介函數程式設計
- 函數語言程式設計入門函數程式設計
- C#函數語言程式設計C#函數程式設計
- Swift の 函數語言程式設計Swift函數程式設計
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- .NET併發程式設計-函數語言程式設計程式設計函數
- 函數語言程式設計-鏈式程式設計RAC函數程式設計