函數語言程式設計的興衰(Composing Software 1)

Dominic_Ming發表於2018-01-03

最近都在緊張的準備期末,然後為即將開始的19屆實習春招在panic,覺得自己好慌,找不到實習怎麼辦)

不過發現了之前翻譯過文章,這個是一個系列的文章,也算是我函數語言程式設計的入坑之作吧

只是翻譯了第一篇,第二篇第三篇都在progress中,大家有興趣的話我就就陸續放出來吧

沒有就接著坑了。。。

我六歲的時候很喜歡和我的朋友玩電腦遊戲。他家有一個專門的房間放滿電腦。對於我來說,他們家就像一片魔法天地吸引著我。在花了很多時間玩過很多遊戲後,我問我的朋友,”我們該怎麼做一款出來呢?“

他也不知道,所以我們去問了他爸爸,他爸爸從書架高處拿下一本用Basic寫遊戲的書。所以我開始了我的程式設計之旅。在學校開始教代數的時候,我早就學過了,因為程式設計就是代數。

組合式程式(Composing Software)的興起

在電腦科學初期,在很多電腦科學理論在電腦上實踐在電腦上之前,有兩個偉大的電腦科學家:Alonzo Church和 Alan Turing。他們發明了兩種不同但是都被廣泛使用的計算模型。兩個模型都可以將任何可計算的模型計算。

Alonzo Church 發明了λ演算。λ演算是一個基於函式應用的普遍模型。Alan Turing以圖靈機著稱,圖靈機是一個在一卷膠帶定義了裝置和操作符的普遍模型。

在這兩組模型的合作中展示了,其實兩種模型在功能上是殊途同歸的。

λ演算主要是關於函式組合。從函式組合的角度來思考問題,是非常直觀的,而且對於組合程式非常有效的。在接下來,我們將討論函式組合在程式設計中的重要性。

說λ演算很特別一下有三個理由:

  1. 函式通常是匿名的。在JavaScript裡面, const sum = (x, y) => x + y 的右運算元是一個匿名函式表示式。
  2. 在λ演算中函式只接受單一輸入,是一元的。如果你需要更多的引數,那麼函式會接受一個輸入後返回一個新的函式,來接受新的引數。多元函式(x, y) => x + y 可以表示為x => y => x + y 這樣的一元函式。這樣的變化被稱為程式設計的柯里化(currying)
  3. 函式是第一級的,這意味著函式可以用來作為其他函式的輸出,函式可以返回函式。

這些特性就賦予了組合式程式,使用函式作為基礎構建模組的能力。在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() 的簽名, 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!')
複製程式碼

可以被這樣表示:

img

λ演算對程式設計產生了巨大的影響,直到1980年,有許多基於組合函式的電腦科學研究成果。Lisp誕生於1958年,就受到了λ演算很大的影響。如今使用的語言中,Lisp依然是一門第二老的語言。

我是通過AutoLISP瞭解的Lisp。AutoLISP是一個用於CAD語言。AutoCAD廣受歡迎當然支援AutoLISP,但是基本上CAD的主要軟體都支援AutoLISP。Lisp在如今還是一門很熱門的語言有三個原因:

  1. 學習Lisp的符號和語法差不多一天就夠了。
  2. Lisp都是函式組合,是一種優雅的結構化程式設計方式。
  3. 我知道最棒的CS課本: Structure and Interpretation of Computer Programs使用著Lisp

組合式程式(Composing Software)的衰落

在二十世紀七十年代,建立程式的模式於簡單的組合檢票漸遠,成為了工業流水線式的生產。之後又有了物件導向程式設計,一個關於元件封裝和資訊傳遞的好主意。不過由於一些熱門的語言扭曲,變成了繼承和類關係的噩夢。

函式是程式設計在學術和應用上都失去了地位,僅僅殘存在一些有執念的極客,常青藤高塔中的教授,還有一些沒有因Java風潮而著迷的學生那裡。

對於大部分的人來說,這都是一個黑暗的時代。

組合式程式(Composing Software)的再次興起

到了2010年左右,發生了一件好事:JavaScript大爆發。在2006年以前。JavaScript被認為是一個做網頁動畫的玩具語言,但是其實有很多強大的特性隱匿其中,即λ演算的特性。人們開始口耳相傳的一個“新的概念”:“函數語言程式設計”。

到了2015年,組合式程式的概念又開始興起。為了讓他更普遍,JavaScript也升級了新的特性,加入了箭頭函式,使函式,柯里化,以及λ表示式更加直觀可讀。

箭頭函式就像是函式式爆發的火箭燃料,以至如今已經很難見到不怎麼使用函數語言程式設計的JavaScript程式了。

組合讓軟體模型和行為都更加簡單,優雅,直觀。使用一些輕量而重要函式來構建大一些的程式元件,函式式的編寫程式更加易於測試,理解,組織,引入。

原文:The Rise and Fall and Rise of Functional Programming (Composing Software)

作者:Eric Elliott

翻譯:Dominic Ming

相關文章