Sunday, January 15, 2017

choose the programming language

記憶中,大學的時候,趨勢科技舉辦的百萬程式大賽。系上有兩隊去參加。其中一隊是號稱為 F4 的隊伍,成員都是系上公認實作能力一等一的學長。另一隊則是比較像是雜牌軍。然而,參賽結果卻相當令人意外,F4 第一關就中箭落馬,雜牌軍則是過關斬將到最後一關,而且有得到名次。後來,聽雜牌軍隊講他們成功的要件: 用 C# 而不是 C++ 來實作。這樣子的作法會有下列的好處: (1) 實作起來比較快。 (2) 當遇到沒有寫好的部分,只是跳出 exception ,而不是程式直接 crash 。

上述的故事,在我日後的職場生涯偶爾想起。從這個故事中得到的啟發是:
「選擇正確的 technology stack 有時候對於軟體公司的影響,不輸給選擇好的員工。」

選擇 technology stack ,這個題目還是有點困難,先從「選擇 programming language 」這個題目開始吧。如果是小公司、小團隊、該如何選擇合適的 programming language 呢?從我的觀點的話,我會認為,應該優先考慮四件事:
  1. productivity
  2. learning curve
  3. core library & third party library
  4. performance
第一件事是「程式語言的生產力」,這件事很多人都已經知道了。然而,有寫過的人總是有基於自身經驗的認知,沒有寫過數種語言的人則主要依賴書本上的數據。也因此,這邊我用 lines of code 來比較,因為我傾向相信某個論文提出的觀點,「相同的時間內,程式設計師可以寫的總行數是類似的。」也因此程式語言所決定的生產力與它的 lines ratio 極為相關。下圖取自 code complete 一書,圖中的 lines ratio 是指實現同樣的功能為前提之下, lines ratio =  C語言需要行數除某一程式語言需要的行數。而 Paul Graham 在他的推荐 Lisp 文章 (Revenge of the Nerds) 中,表示 Lisp 的 lines ratio 一般而言是 7~ 10 ,如果面對複雜的問題、且使用進階的技巧,甚至可以到達 20 。
LanguageStatements ratio[35]Lines ratio[36]
C11
C++2.51
Fortran20.8
Java2.51.5
Perl66
Smalltalk66.25
Python66.5

第二件事是「學習曲線」。學習曲線陡峭的程式語言,也就意味著該語言的使用者會變少。對公司的立場來說,也就意謂著不容易找合適的工程師。舉個例子,就我自己學習 clojure 語言 (Lisp 的方言) 的經驗來說,確實不那麼容易學,因為很多觀念都不存在於過去的經驗。從 TIOBE 來看的話, Lisp 語言曾經一度是排行前 20 的程式語言,應該是因為學習曲線等因素,始終是小眾的語言。

第三件事是「函式庫支援」。這個要素其實跟「生產力」也類似。畢竟,如果主要選用的程式語言,沒有合適的函式庫支援時,往往軟體就是要透過使用多種程式語言來完成,又增加了複雜度和維護成本。

最後一件事才是「效能」。對於效能一事,我本來一直有一種誤解,覺得「程式語言之間」會有效能的差異。然而,一回我查了網路的文章,才發覺這個來自經驗的想法不太正確。程式語言和它的效能是脫勾的。效能是跟語言的實作 (implementation) 才有關系。所以,要探討 Java 語言的執行效能,重點要去探討 JVM 的實作。而一些流行的 scripting language 為何要特別設計出可以編譯到 JVM 的版本?重點是在於,做出可以在 JVM 執行的版本,比起直接將該語言做成 native machine code 省事太多,同時,JVM 又已經「夠快」了,有著幾乎不輸給 native machine code 的效能。這邊特別提一下,很多人也跟我一樣,對 JVM 有著誤解,以為 JVM 很慢,跟一般的 scripting language 所用的 engine 或是 VM 差不多的效能。這個也是來自經驗的誤解。 JVM 只是啟動比較慢,而這一點是有技巧可以克服的。