iThome 網站首載:對Y Combinator的好奇與挑戰
各行各業都一樣,必須不斷地學習與提昇自身技能,方不至於坐吃山空既有能力與經驗;面對越來越多的技術、各式各樣的生態,做為程式人該怎麼選擇投資的對象?跟隨技術潮流只會流於盲目的技術追逐,相信技術預言有時跟擲筊沒兩樣,還得避免誤信神棍謊言;對個人來說,或許技術的選擇不用這麼複雜,只需回歸原點,順從自己的好奇心並享受打怪的興奮感,一切都只是為了有趣。
- 技術謎團的DRY原則
身為開發者必然知道DRY原則,也就是Don't Repeat Yourself(沒聽過?你是冒牌開發者嗎?),程式開發上的重複有各種形式,大多是程式碼上的直接重複,有時是命名或流程,也有可能是架構上的重複,在《The Pragmatic Programmer》中談到「系統中的每份知識都應該是獨特、無岐義並且具備權威性」,身為開發者,對於重複會具有敏感性,無論是何種重複,只要挑動了敏感神經,就會想實行DRY原則來消弭重複。
對於技術的投資選擇,我奉行的是技術謎團的DRY原則,我平常會去跟隨(follow)一些技術網站,這些網站可能是綜合性,也可能是特定語言或生態系,除此之外也會跟隨一些開發者的動態,無論那是透過部落格、專頁或微網誌等平台,閒逛一些社群討論區也是經常之事,像是JavaScript.tw、Python Taiwan、node.js台灣、TWJUG、AWS、Hadoop、Ruby等各式各樣的社群,你可能會問,這麼多的資訊來源,有可能全部消化嗎?這還用問嗎?答案當然是「不可能」!
大多數情況下,我都是看看文件標題,如果標題引起了好奇心,就會進一步看看文件中的大綱(就是那些
h1
、h2
或加粗了的文字),沒有大綱的話,就看看前幾個破題段落,如果是社群討論,就看看前幾個討論內容,在這個過程中,有些名詞會躍入眼簾,儘管不知道那是什麼東西,也可能在心中形成了一些小小謎團,有些名詞會模糊糊看懂一些,但卻看到更多不同面向的討論與解釋,同一名詞出現的頻率越多,圍繞在該名詞周圍的謎團越多,一而再、再而三的謎團重複形成,直到我不耐煩時,就會想要實行DRY原則去重構該名詞周圍的謎團。- 對Y Combinator的好奇
最近對Y Combinator產生了好奇,不過在談到Y Combinator之前,得從過去大家都又開始熱衷Ajax說起,當時得到的概念是,要發揮JavaScript能力,毫無疑問地得善用一級(First-class)函式,例如同樣是迭代清單,JavaScript撰碼風格是使用清單物件的
forEach
函式,而不是透過for
迴圈走訪元素;老實說,一級函式的概念接受上並不難,後續在學習Python、Ruby的過程中,初步也認為lambda、Block等都是類似的概念,不過偶而地,文件或書中會出現Closure這個神秘的名詞...只要是將函式視為值的語言中,Closure這名詞就可能會一而再、再而三地出現,而且經常伴隨著「函數式程式設計(Functional programming)」這看似更神秘的典範,好奇心讓我進一步想認真瞭解Closure,有時以為自己看懂了,卻又發現另一種說法,看似清晰而後又模糊的過程一再重複,終究讓我感到不耐煩,唯一能確定的就是Closure這東西來自函數式程式設計,為了弄懂,與其繞著各種非純函數式語言來摸索函數式程式設計,不如選擇好好研讀Haskell這個純函數式語言。
好奇心促成了對Haskell進一步的瞭解,也意外發現了一片天,純函數式的許多概念,其實與不少程式設計原則不謀而合,於是我想要挑戰看看各種語言來實現純函數式風格的可能性,因而將我網站上〈常見程式演算〉中的題目,分別以Java、Python、Scala、Ruby、JavaScript等語言且運用函數式風格來實現,這真的是個不小的挑戰,然而中間也獲得了不少啟發與樂趣;在研究與挑戰函數式程式設計的過程中,偶而地,會出現Y Combinator這個名詞!出現的次數足以引起我的好奇心,不過圍繞在該名詞周圍的謎團還不夠多 ...
- 挑戰Y Combinator
Y Combinator是個很神奇的東西,簡單來說,是個可以運行程式的程式(a program that runs programs),因為這個概念太酷了,美國有間創投公司就命名為Y Combinator,因為它們是間協助新創公司的公司。我不記得第一次是在哪邊看到Y Combinator這個名詞了,只記得是篇談Lambda演算的文件,函數式程式設計的理論基礎就是Lambda演算,總之,為了更進一步瞭解函數式程式設計的過程中,難免會接觸到Y Combinator這個名詞。
不過顯然地,當時我沒有耐心進一步深究Y Combinator,略略看過之後覺得暫時不用理解,直到JavaScript.tw社群中出現過幾次用JavaScript來實現Y Combinator的鏈結分享,印象最深刻的是iThome上出現的〈挑戰函數式Javascript之Y組合子應用〉這篇文章;某次在Python Taiwan社群中,看到有人討論用lambda來實現一行的費式數(Fibonacci number),一時興起也來挑戰,完全使用匿名函式實現費式數,當時完全照心中想法來挑戰,這篇討論後來沉寂了一陣,直到近日重新被提起時,有朋友提到了Y Combinator!
又是Y Combinator?我問到當初的寫法就是Y Combinator嗎?在討論中朋友提供了〈The Y Combinator explained with JavaScript〉這篇文件,不過當中那些JavaScript的function關鍵字看得令人十分眼花,大概瞭解文件中的概念後,我決定用Python挑戰自行實現Y Combinator,這玩意兒一開始很複雜,出發點就是想辦法讓匿名函式能進行遞迴,過程中得不斷假設某些東西存在,最後證明那些東西真的存在,當不斷的假設與實現使得程式越來越複雜時,神奇的東西就出現了,它真的存在,接著就是把那些複雜多餘的東西逐一去除,得到的函式就是Y Combinator的實現!
Y Combinator怎麼用?想想怎麼寫個匿名的遞迴函式,例如計算階乘可以寫成
lambda n: 1 if n < 2 else n * fact(n - 1)
,只是fact函式從何而來?你不能使用變數fact = lambda n: 1 if n < 2 else n * fact(n - 1)
,這樣就不能算是匿名了,你只好寫成lambda fact: lambda n: 1 if n < 2 else n * fact(n - 1)
,只是誰能提供fact
給這個匿名函式?就是先前挑戰中得到函式,也就是y = lambda f: (lambda x: f(lambda n: x(x)(n)))(lambda x: f(lambda n: x(x)(n)))
,把方才的(lambda fact...)
丟給y
函式,它就會幫你產生一個fact
,而y執行後傳回的函式,就是一個可遞迴運算階乘的匿名函式,y
能產生的匿名函式不只是能遞迴運算階乘,丟給y
一個lambda fib: lambda n: n if(n == 0 or n == 1) else fib(n - 1) + fib(n - 2)
會如何?傳回的就是可遞迴運算費式數的匿名函式了。- 一切都是為了有趣
好奇之後的挑戰,樂趣就在神奇東西出現的哪一瞬間,之後我又回去重看了以前設為書籤的幾個Y Combinator的文件,然後就完全看懂了,這種成就感難以言喻,接下來就會去想,這有沒有實用性?在網路搜尋了一陣後,似乎沒什麼實用性,開發者在好奇與挑戰之後,有時是會得到這樣的結果,然而有時以會有實質的回饋,有時這類回饋有可能在若干時日後才會察覺。舉例來說,我並沒有預料到挑戰函數式程式設計之後,會得到不少設計上的概念啟發,更沒預料到在看JDK8的Lambda專案時,有那麼大的助益。
那麼Y Combinator就當好玩吧!至少挑戰的過程我樂在其中,以後有沒有用那就再說了!回頭想想,投入程式設計領域的一開始,不就是因為好奇與挑戰成功帶來了不少樂趣?何必當技術預言家呢?一開始就投入JavaScript而覺得有趣的開發者,大都不會預料到它會鹹魚翻身!就個人來說,技術的選擇不用考量太多複雜因素,只要你對該技術產生好奇從而產生挑戰的欲望,那就開戰並且享受過程中帶來的樂趣吧!