突然覺得可以分享一下自己學程式語言的經驗,也許可以啟發一些學生或是已經在業界但是想不斷增進自己能力的工程師朋友們。 (實在太久沒寫文了,文筆差請見諒)
我最早接觸程式語言的時間大概是小學五六年級,當時 Flash 正在起飛,版本應該是 Flash 4 升 5 的中間。 沒記錯的話應該是這程式語言演變成 ActionScript 之前。 某天去逛書店的時候看到有一本大約是 200 元專門講 Flash 遊戲設計的雜誌。 讀了這本雜誌,並在大部分觀念都沒搞懂的情況下亂寫了一些小東西。不過所有東西都是半成品,例如想做個打磚塊, 但做了「平台移動」跟「牆壁碰撞反彈」就停下來了,並沒有把磚塊的部分做出來。不過這大概是我個性上的缺陷吧。 很容易事情做一半就感到無趣了。至於中間學到的應該只有變數跟判斷式吧。印象中並沒有學到迴圈, 迴圈跟時間控制都是直接使用「影格」跟 goto 配合。後來陸陸續續買了兩三本 Flash 相關的書籍,不過都是看看而已。
第二次接觸程式學習是在國中,當時有資訊老師非常熱衷資訊教育,辦了一個利用中午午休時間來教學生寫程式的課。 使用的語言是 Basic。一點趣事:要參加這個課程需要經過甄選,甄選的方式是一個小紙筆測驗,印象中當初不少人報考, 不知道是不是因為大家其實不太想午休的關係 XD。這課程其實也就是教一些基礎的判斷跟迴圈。 在最後最後有用 VB 寫了個半殘計算機。
升高中後覺得 Basic 不是一個常見的語言,所以跑去買了 C 語言的入門書。加入了資訊研究社,
在老師的帶領下開始學習基本演算法,刷刷 ACM,當時英文爛到不行(雖然現在還是爛)
只能靠 luckycat 的中文翻譯不然連題目都看不懂 :p
有去打了幾場資訊競賽,但大部分的成績都不怎麼理想。
也嘗試報考了 IOI (奧林匹亞資訊競賽)選訓營。我還記得我寫對了數獨題,但是掛在最簡單的題目,
而且還是錯在判斷式中寫了 =
而不是 ==
。大概這題沒錯就可能會進選訓營了吧?
大學考到了資管系,原因是英文不及格 XD,不然應該會直接上資工系。 不過我就毅然決然地去修了資工系的計程,後來也順利轉到資工系。 本來以為高中社團的訓練可以讓我輕輕鬆鬆過關的,沒想到期中考考了個全班平均分 3x。 考試當天就體驗到了什麼叫做「當全班都不會寫的時候,還是有神人可以一小時 clear,帥氣走出考場並拿出 9x 的高分。」 而剛進大學的我還不知道「開根號乘以十」是常態,考完期中考還去問教授該怎麼辦 XD
系上的課程安排其實並不會教太多程式語言,其實也就教了 C 跟 Java,design pattern 是個選修課。 但有些課程也需要其他的程式語言,但基本上不教,直接跟你說用這個語言,你自己想辦法學起來。 聽起來滿不負責任的,但其實我覺得合理,畢竟大部分的程式語言的差異並沒有這麼大, 每個都教其實有點浪費時間,畢竟學生 project 其實不太需要用到某些 programming language 的特殊設計或功能。
也許是因為我忽略了,當時的課程設計並沒有講太多實務開發,更沒有對於程式語言有更近一步分析講解的課程。 其實我覺得這點非常可惜,也許只是因為當時不像現在各種語言百花齊放, JavaScript 各種 dialect、寫個 iOS App 可以可以用 Objective C 或 Swift 等等。 所以學校並不覺得「程式語言」需要是個獨立的課程。
升大三暑假,有同學說在接案賺錢,問我要不要一起,我當時覺得一直接家教不是辦法(尤其是我又不是特別會教), 所以花了兩三週去 w3school 學了 PHP,想說同學會罩我,就硬著頭皮上了。 事後發現根本超虧本,寫出來的系統也是漏洞百出,根本不堪回首 orz
大三這年出現了 iPhone、android,連帶各種網路技術蓬勃發展。 我在這年學了 Objective C/Python/JavaScript 等等等等, 大部分都是找網路上免費資源,例如 iPhone Objective C 就是直接看 iTune U 上面的 Stanford 課程。 但其實都學得非常粗糙、一知半解,什麼 lifecycle memory 管理都比較隨意。 不過因為修了某教授的課,被教授介紹去他朋友的公司實(ㄌㄧㄢˊㄐㄧㄚˋ)習(ㄌㄠˊㄍㄨㄥ)寫 App, 在大四這一年累積了一點點實務經驗。其實因為 mobile app development 都還在萌芽時期, 現在回顧,全世界基本上都是追隨「原廠」建議設計,大家都還在摸索 design pattern 在這領域的使用方法。
實習一陣子後,覺得這樣實在不行,太窮了。 後來才決定出來自己想辦法接案。 在這個時候 Ruby on Rail 正在竄起,我也跟了潮流學了一些,也順利接到一些案子。 碩一時 NodeJS 竄起,我也接了一些 NodeJS project,不過使用的語言是 CoffeeScript 大概在這個時間點 JavaScript 的生態系開始快速成長,NodeJS 生態系也開始模仿 Rails, 並且開始有不少人提倡 TDD, DI 等等軟體工程的觀念。
其實到這個時間點,我都不算是對程式語言有什麼特別的見解, 就是接案導向學習,案子需要什麼就去學什麼。 一直都覺得自己缺了什麼,開發軟體不應該是一個這麼沒有結構的東西才對。 不過也 frontend, backend, ios, android 都摸了一圈。 因為接觸不同的系統跟架構,讓我開始對程式架構有一些有趣的看法。 應該是在各種技術文中偶然看到了 Functional Programming, 才發現原來這些有趣的想法其實就是 immutable 跟 pure function。
為了了解更多,我決定去上 coursera 上的 Functional Programming Principle in Scala。 而這門課讓我了解到原來一些語言上的結構其實都可以用 function 來 model (例如 loop 可以用 recursive function 跟 callback 實作)。 原來我之前學這麼多程式語言、系統、架構,都是知其然不知其所以然。 我開始想,既然 Scala 這種 mult-paradigm language 就能帶給我這麼多啟發, 那我是不是應該要去找「正統」的 pure functional lanauge 來學習看看呢? 或許我可以從這個過程中學到更多。
於是我嘗試了 ClojureScript,會想選這個的原因是因為它算是 lisp 的近親, 而 lisp 又是最老牌知名的 FP 語言,再來就是當時我對前端開發比較有熱誠。 不過在讀完一本書以後,並不覺得有什麼特別的啟發。於是我嘗試了我的下一個選項: Haskell。
以往學習程式語言的過程是這樣的:入門書都會從基本語法開始,然後介紹進階語法,最後討論範例。 對於有學過一門程式語言的人來說,閱讀這樣的書籍其實非常快,基本沒什麼難度, 因為幾乎都可以對應到自己過去的經驗。但學習 Haskell 的過程非常的不一樣,雖然跟 ClojureScript 一樣, 基礎語法比其他語言更少,連 for loop 都沒有。type 宣告又極度精簡,不像 Java 最少最少都要四五行, 甚至在某些案例下 type 宣告行數來說,Java 會比 Haskell 多出 10 到 20 倍。 基礎語法的章節基本上都可以在一兩個小時內看完,但後面還有十幾個章節講解如何使用少少的語法來構築常見的功能, 而每個章節的難度基本上成等比增加。每個章節也都可以讓我等比級數地認知到我各種之前的「知其然不知其所以然」。
由第一本 Haskell 書籍啟發,大概在 2016 年之後我開始大兩閱讀 Haskell 相關技術文章, 然後開始接觸到一些相關的抽象數學,例如 Category Theory, 同時也發現一些使用 FP 來探討軟體架構的書籍跟論文。 而在實務工作上也開始應用這方面的知識來規劃系統架構或解決效能問題。 我發現這些知識可以更容易的理解系統的本質,進而提出未被發現的架構缺陷。
現在也在繼續這樣的學習中,接下來除了工作上需要的學習以外,應該會繼續看一些 Dependent Type 的書。