本文做者: Eric Elliott
編譯:鬍子大哈 javascript翻譯原文:huziketang.com/blog/posts/…
英文鏈接:The Rise and Fall and Rise of Functional Programming (Composing Software)前端
轉載請註明出處,保留原文連接以及做者信息java
本文是「組合式軟件」系列的一篇文章,從頭開始學習函數式編程和使用 JavaScript ES6+ 進行軟件編程。請繼續關注,後面還有不少相關內容。react
在我 6 歲的時候,我天天花不少時間和我最好的朋友一塊兒打遊戲,他們家裏有不少電腦。對我來說它有種魔幻版不可抗拒的力量。有一天我忽然問我朋友:「咱們怎樣才能本身作一個遊戲呢?」編程
他也不知道,因此咱們一塊兒去問他的爸爸,叔叔從很高的架子上拿下來一本書:Basic。我也由此開始了個人編程之旅。後來大學都有代數這門課程,而我對它已經很熟悉了,由於編程裏面代數是基礎,處處都是代數。數組
在計算機科學剛剛起步的時候,不少計算機科學的理論都尚未落地。那時候有兩個偉大的計算機科學家:阿隆佐·丘奇和阿蘭·圖靈。他們創造了兩個不一樣的,可是具備同等效力的通用計算模型。兩個模型均可以計算任何能夠計算的東西(着重強調,「通用」)。瀏覽器
阿隆佐·丘奇發明了 λ 演算, λ 演算是基於函數應用的通用計算模型。阿蘭·圖靈則因圖靈機而廣爲人知。圖靈機定義了一個理論上的設備,它能夠控制條帶上的符號。他們合做證實了 λ 演算和圖靈機是功能等價的。架構
λ 演算所有都是關於函數組合。函數組合在軟件開發中是很是富有表現力和說服力的。本文中,咱們會討論函數組合在軟件設計中的重要性。app
這裏有三點關於 λ 演算的特殊說明:編程語言
const sum = (x, y) => x + y
的右邊是匿名函數,即 (x, y) => x + y
。(x, y) => x + y
能夠表達爲一個一元函數:x => y => x + y
。這種 n 元函數到一元函數的轉化叫作柯里化。這些特徵一塊兒構成了簡單且容易理解的規則,在組合式軟件中使用函數做爲主要編碼單元。在 JavaScript 中,匿名函數和柯里化函數都是可選特徵,也就是說 JavaScript 支持 λ 演算的主要特徵可是並不強制使用。
經典的函數組合是把一個函數的輸出做爲另外一個函數的輸入,例以下面的組合:
f·g複製代碼
能夠寫成:
compose2 = f => g => x => f(g(x))複製代碼
下面是如何使用它:
double = n => n * 2
inc = n => n + 1
compose2(double)(inc)(3)複製代碼
compose2()
函數接受 double
函數做爲第一個參數,inc
函數做爲第二個參數,最後應用參數 3 到這兩個函數組合上。再看一下 compose2()
的聲明,f
是 double()
,g
是 inc()
,x
是 3
。函數調用 compose2(double)(inc)(3)
,其實是三個不一樣的函數調用:
double
返回一個新函數 1;inc
爲參數而且返回一個新函數 2;3
爲參數而且計算 f(g(x))
,即 double(inc(3))
;x=3
傳遞給 inc()
;inc(3)
計算結果是 4
;double(4)
計算結果是 8
;8
。組合式軟件的過程能夠用函數組合圖來表達,看下面代碼:
append = s1 => s2 => s1 + s2
append('Hello, ')('world!')複製代碼
能夠用圖來模擬表示:
λ 演算對軟件設計的影響是深遠的,直到大約 1980 年,計算機科學界不少有影響力的品牌,都是採用函數組合的方式來開發本身的軟件。Lisp 是 1958 年發明的,它深受 λ 演算的影響。直到今天,Lisp 是依舊廣爲使用的第二大歷史悠久的語言。
我是經過 AutoLISP 知道的 Lisp,AutoLISP 是在最流行的電腦輔助設計(CAD)軟件——AutoCAD,中使用的腳本語言。AutoCAD 太流行了,使得其餘全部的 CAD 應用幾乎都支持 AutoLISP 以保持其兼容性。Lisp 依然可以在計算機科學課程中廣爲使用有三個主要緣由:
在 1970 到 1980 年期間,軟件開發的方式開始發生變化,簡單的組合式開發再也不受寵。出現了面向對象編程,它基於組件封裝和信息傳遞的思想,在當時是很是先進的。代碼經過繼承來實現複用,繼承關係是一種叫作 is-a
的關係。
函數式編程逐漸被邊緣化,被拋棄到學術界和非主流的場外。在 1990 — 2010 年期間對三種人造成了甜蜜的困擾,一種是編程極客,一種是大學教授,一種是逃離了 Java 思想強制灌輸的幸運的學生。而對於咱們來說,這 30 年的軟件開發有一點噩夢般的感受,黑暗的年代。
2010 年左右,有個巨大的變化:JavaScript 爆發了。在 2006 年之前,JavaScript 一直被認爲是一種玩具式的編程語言,能夠在瀏覽器中作一些很可愛的動畫,可是在這背後隱藏着潛力巨大的特色,即 λ 演算的重要特徵。人們開始逐漸在私下裏談論「函數式編程」。
到 2015 年,用函數組合來開發軟件從新開始流行起來。爲了簡化使用,JavaScript 規範也作了 10 年以來的首次重大升級,增長了箭頭函數。箭頭函數使建立和使用函數、柯里化和 λ 演算變得很容易。
箭頭函數對於 JavaScript 函數式編程的爆發起到了推進劑的做用。如今不多看到那種不用函數式編程的大型應用了。
組合的方式能夠簡潔清晰地描述軟件的行爲,把一些小的、肯定性的函數組合成大的組件,進而造成軟件,這樣的軟件很容易組織、理解、調試、擴展、測試和維護。
在讀接下來文章的時候,但願你能經過例子本身動手作實驗。回想一下當本身仍是的孩子的時候,把一些東西拆開,本身再學着組裝、拼接。從新找回童年探索事物的感受,但願你能享受這個過程。
若是本文對你有幫助,歡迎關注個人專欄-前端大哈,按期發佈高質量前端文章。
我最近正在寫一本《React.js 小書》,對 React.js 感興趣的童鞋,歡迎指點。