[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)

guoyang134340發表於2017-04-14

[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)

煙霧的方塊藝術 —MattysFlicks —(CC BY 2.0)

注意:這是從基礎學習函數語言程式設計和使用 JavaScript ES6+ 編寫軟體的第一部分。保持關注,接下來還有很多!

當我 6 歲時,我花了很多時間跟我的小夥伴玩電腦遊戲,他家有一個裝滿電腦的房間。對於我說,它們有不可抗拒的魔力。我花了很多時間探索所有的遊戲。一天我問他,“我們怎樣做一個遊戲?”

他不知道,所以我們問了他的老爸,他的老爸爬上一個很高的架子拿下來一本使用 Basic 編寫遊戲的書籍。就那樣開始了我的程式設計之路。當公立學校開始教授代數時,我已經熟稔其中的概念了,因為程式設計基本上是代數。無論如何,它都是。

組合型軟體的興起

在電腦科學的起步階段,在大多數的電腦科學在電腦上完成之前,有兩位偉大的電腦科學家:阿隆佐·邱奇和艾倫·圖靈。他們發明了兩種不同、但是普遍通用的計算模型。兩種都可以計算所有可被計算的東西(因此,“普遍”)。

阿隆佐·邱奇發明了 lambda 表示式。lambda 表示式是基於函式應用的通用計算模型。艾倫·圖靈因為圖靈機而知名。圖靈機使用定義一個在磁帶上操作符號的理論裝置來計算的通用模型。

總的說,他們共同說明了 lambda 表示式和圖靈機功能上是相等的。

lambda 表示式全是函式組成,依靠函式來編寫軟體是非常高效和有意義的。本文中,我們將會討論軟體設計中函式的組合的重要性。

有三點造就了 lambda 表示式的特別之處:

  1. 函式都是匿名的,在 JavaScript 中,表示式 const sum = (x, y) => x + y 的右側,可以看作一個匿名函式表示式 (x, y) => x + y
  2. lambda 表示式中的函式只接收一個引數。他們是一元的,如果你需要多個引數,函式將會接受一個輸入返回一個呼叫下一個函式的函式,然後繼續這樣。非一元函式 (x, y) => x + y 可以被表示為一個像 x => y => x + y 的一元函式。這個把多元函式轉換成一元函式的過程叫做柯里化。
  3. 函式是一等公民的,意味著函式可以作為引數傳遞給其他函式,同時函式可以返回函式。

總的說來,這些特性形成一個簡單且具有表達性的方法來構造軟體,即使用函式作為初始模組。在 JavaScript 中,函式的匿名和柯里化都是可選的特性。雖然 JavaScript 支援這些 lambda 表示式的重要屬性,它卻並不強制使用這些。

這些經典的函式組合方法用一個函式的輸出來作為另一個函式的輸入,例如,對於組合:

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() 函式所寫的,fdouble()ginc(),同時 x3。函式 compose2(double)(inc)(3) 的呼叫,實際上是三個不同函式的呼叫:

  1. 首先傳入 double 同時返回一個新的函式。
  2. 返回的函式傳入 inc 同時再返回一個新的函式。
  3. 再返回的函式傳入 3 同時計算 f(g(x)),最後實際上是 double(inc(3))
  4. x 等於 3 同時傳給 inc()
  5. inc(3) 等於 4
  6. double(4) 等於 8
  7. 函式返回 8

組合軟體時,可以被看作一個由函式組合的圖。看一下下面:

append = s1 => s2 => s1 + s2
append('Hello, ')('world!')複製程式碼

你可以想象成這樣:

[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)

lambda 表示式對軟體設計產生了很大的影響,在 1980 年之前,電腦科學領域很多有影響的東西使用函式來構造軟體。Lisp 在 1958 年被創作出來,很大程度上受到了 lambda 表示式的影響。如今,Lisp 是廣泛使用的第二老的語言了。

我通過 AutoLISP:一個作為指令碼語言被用於最流行的計算機輔助設計(CAD)軟體:AutoCAD,接觸到它。AutoCAD 很流行,實際上所有其他的 CAD 軟體都相容支援 AutoLISP。Lisp 因為以下三點原因被廣泛作為電腦科學的課程:

  1. 可以很容易的在一天左右學習 Lisp 基礎的詞法和語法。
  2. Lisp 全是由函式組成,函式組合是構造應用非常優雅的方式。
  3. 我知道的使用 Lisp 的最棒的電腦科學書籍:計算機程式的結構與解釋

組合型軟體的衰落

在 1970 到 1980 中間的某段時間,軟體的構造開始偏離簡單的組合,成為一串線性的讓計算機執行的指令。然後物件導向程式設計 — 一個偉大的關於元件的封裝和資訊傳遞的思想被流行的程式語言扭曲了,變成為了特性的重用所採取的糟糕的繼承層次和 is-a 關係。

函數語言程式設計語言退居二線:只有程式設計極客的痴迷、常春藤盟校的教授和一些幸運的學生可以在 1990 — 2010 年間逃離 Java 的強迫性學習。

對於我們的大多數人來說,已經經歷了大約 30 年的軟體編寫噩夢和黑暗時期。

組合型軟體的興起

在 2010 年左右,一些有趣的事情發生了:JavaScript 的崛起。在大概 2006 年以前,JavaScript 被廣泛的看作玩具語言和被用製作瀏覽器中好玩的動畫,但是它裡面隱藏著一些極其強大的特性。即 lambda 表示式中最重要的特性。人們開始暗中討論一個叫做 “函數語言程式設計的” 酷東西。

[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)

我一直在告訴大家 #JavaScript 並不是一門玩具語言。現在我需要展示它。

在 2015 年,使用函式的組合來編寫軟體又開始流行起來。為了更簡單化,JavaScript 規範獲得的數十年來第一次主要的更新並且新增了箭頭函式,為了更簡單的編寫和讀取函式、柯里化,和 lambda 語句。

箭頭函式像是 JavaScript 函數語言程式設計飛昇的燃料。現在很少看見不使用很多函數語言程式設計技術的大型應用了。

組合型可以簡單、優雅的表達軟體的模型和行為。通過把小的、確定的函式組合成稍大的元件並構成軟體的過程,可以更為簡單的組織、理解、除錯、擴充套件、測試和掌控。

你在閱讀下一部分時,可以使用例項實驗,記住要把你自己當孩子一樣把其他的思想扔在一邊在學習中去探索和玩耍。重新發現孩童時發現新事物的欣喜。讓我們來做一些魔術吧。

接下來的第二部分:“為什麼要用 JavaScript 學習函數語言程式設計?”

下一步

想更多的學習 JavaScript 的函數語言程式設計?

Learn JavaScript with Eric Elliott,什麼,你還沒有參加,out 了!

[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)
[譯]跌宕起伏的函數語言程式設計(軟體編寫)(第一部分)

Eric Elliott“Programming JavaScript Applications” (O’Reilly) 和 “Learn JavaScript with Eric Elliott” 的作者。他曾效力於 Adobe Systems, Zumba Fitness, he Wall Street Journal, ESPN, BBC, and top recording artists including Usher, Frank Ocean, Metallica 和其他一些公司。

他和她的老婆(很漂亮)大部分時間都在舊金山灣區裡。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃

相關文章