標籤:des style 使用 資料 width 問題
1.1 什麼是函數式編程?
想給函數式編程下個明確的定義,是困難的。因為,存在不同的函數語言,但是,並沒有明確的、每種函數語言必須具有的特徵集。儘管如此,函數語言仍有一些共同的屬性,只是表達解決編程問題的風格稍微有點不同。最容易地描述函數式編程,就是把它與最常見的編程風格:命令式編程(imperative programming),進行比較。
[函數語言]
函數式編程的編程風格是強調錶達式計算,而不是執行命令。函數語言中的運算式是用函數組合成基本的值。[Hutton ed. 2002]
這一定義來自學術的郵件清單關於函數語言的常見問題集(FAQ),所以它可能聽起來有點抽象。相信我們,含義會很快變得清淅。第一句“運算式計算”是函數式表示,與命令式代碼中的“執行命令”風格相對。命令式語言中的命令被稱為語句(statements),因此,我們就用這個名詞。讓我們看看兩者的詳細內容:
■語句的執行:程式用一組命令,也稱為語句表示。命令通過建立對象並操縱對象,實現最終結果。使用這種方法,通常使用可改變的對象,代碼描述了需要執行什麼操作才能達到所期望的結果。例如,我們首先製作一杯黑咖啡,這個對象是可改變的,因此,我們可以通過加兩包糖以獲得所需的結果。
■運算式計算:在函數式風格中,程式碼是描述對象屬性的運算式,這個對象就是所需要的結果,不必要指定構造對象所需的步驟,在建立對象之前,是不可能意外使用的。例如,假設我們想要一杯加了兩包糖的咖啡,在加糖之前我們是不能喝的,因為當我們得到這個杯子時,它已經包含了糖[唐軍1] 1。
[
1 製作咖啡的類比, LucaBolognese 也曾經在 2009 年的 TechEd 有關 F# 的著名談話中用過[Bolognese,2009]。這一巧合表明,通過學習函數式編程,你將學會以不同的方式思考,既包括編程問題,也包括下午休息。
]
這聽起來差別可能很細微,但它會導致設計的代碼方式的巨大變化。唯一的公理是我們寫的代碼是運算式,而不是語句序列,但這種方法有很多邏輯的後果。封裝、組合代碼的方式不同了,可以用多種技術寫可重用的代碼,使用更適合表示複雜計算結果的資料結構……清單可以一直寫下去。
定義函數式編程是一回事,更需要理解的是如何把這些概念結合在一起,這兩個主題構成本書的重點。你讀完本書以後,不僅能理解前面的定義,而且對函數式編程的更直接。這才是更為重要的,遺憾的是,不是幾句話就說得清的。
到目前為止,所有這一切聽起來都很抽象,但這本書的標題包含的“實用(Real World)”是有充分理由的。函數式編程可以提供顯著的好處。當遇到下面的情況,就可以用函數方式來解決(就像這本書的作者一樣):
■你發現了嗎,很難預測修改代碼的後果,是由於隱形依賴關係和微妙之處?
■你發現了嗎,自己反覆寫相同的模式,沒少有時間用於處理問題中真正不同和有意義的部分?
■你發現了嗎,很難理清代碼,擔心代碼是否每條語句都以正確的順序,並在正確的條件下執行?
■你發現了嗎,很難表達抽象的東西,它隱藏了代碼是如何執行的,只指出了你想要實現什嗎?
■你發現了嗎,非同步控制流程導致代碼走向類似於意大利麵條,令人抓狂?
■ 你發現了嗎,很難把任務拆分成邏輯上獨立的部分,能夠同時運行多個處理器核心上?
■實際的程式碼為與在單元測試中是否不同?
在我們正式瞭解函數式編程如何提高生產力之前,先簡單地回顧一下其曆史,那是相當的豐富。
[唐軍1]