最近都在緊張的準備期末,然後為即將開始的19屆實習春招在panic,覺得自己好慌,找不到實習怎麼辦)
不過發現了之前翻譯過文章,這個是一個系列的文章,也算是我函數語言程式設計的入坑之作吧
只是翻譯了第一篇,第二篇第三篇都在progress中,大家有興趣的話我就就陸續放出來吧
沒有就接著坑了。。。
我六歲的時候很喜歡和我的朋友玩電腦遊戲。他家有一個專門的房間放滿電腦。對於我來說,他們家就像一片魔法天地吸引著我。在花了很多時間玩過很多遊戲後,我問我的朋友,”我們該怎麼做一款出來呢?“
他也不知道,所以我們去問了他爸爸,他爸爸從書架高處拿下一本用Basic寫遊戲的書。所以我開始了我的程式設計之旅。在學校開始教代數的時候,我早就學過了,因為程式設計就是代數。
組合式程式(Composing Software)的興起
在電腦科學初期,在很多電腦科學理論在電腦上實踐在電腦上之前,有兩個偉大的電腦科學家:Alonzo Church和 Alan Turing。他們發明了兩種不同但是都被廣泛使用的計算模型。兩個模型都可以將任何可計算的模型計算。
Alonzo Church 發明了λ演算。λ演算是一個基於函式應用的普遍模型。Alan Turing以圖靈機著稱,圖靈機是一個在一卷膠帶定義了裝置和操作符的普遍模型。
在這兩組模型的合作中展示了,其實兩種模型在功能上是殊途同歸的。
λ演算主要是關於函式組合。從函式組合的角度來思考問題,是非常直觀的,而且對於組合程式非常有效的。在接下來,我們將討論函式組合在程式設計中的重要性。
說λ演算很特別一下有三個理由:
- 函式通常是匿名的。在JavaScript裡面,
const sum = (x, y) => x + y
的右運算元是一個匿名函式表示式。 - 在λ演算中函式只接受單一輸入,是一元的。如果你需要更多的引數,那麼函式會接受一個輸入後返回一個新的函式,來接受新的引數。多元函式
(x, y) => x + y
可以表示為x => y => x + y
這樣的一元函式。這樣的變化被稱為程式設計的柯里化(currying) - 函式是第一級的,這意味著函式可以用來作為其他函式的輸出,函式可以返回函式。
這些特性就賦予了組合式程式,使用函式作為基礎構建模組的能力。在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
後返回了一個新的函式。 - 之後函式接收了
inc
返回了一個新的函式。 - 新的函式接收了
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廣受歡迎當然支援AutoLISP,但是基本上CAD的主要軟體都支援AutoLISP。Lisp在如今還是一門很熱門的語言有三個原因:
- 學習Lisp的符號和語法差不多一天就夠了。
- Lisp都是函式組合,是一種優雅的結構化程式設計方式。
- 我知道最棒的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