技術雜談:為什麼 Nim 語言無法造成流行

PUBLISHED ON FEB 3, 2018
FacebookTwitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    Nim 是一個新興的編譯語言,其核心理念相當地簡單:Nim 程式碼會轉為等效 C 程式碼,再由 C 編譯器實際編譯軟體。在理想上,這個方向的確是可行的,因為 C 語言問世超過四十年,C 編譯器的優化技術已經相當成熟,與其從頭開始撰寫一套新的編譯器,還不如直接站在巨人的肩膀上。不過,Nim 專案從 2008 年問世,到目前 (2018 年二月) 已經十年了,這個專案並沒有流行起來。筆者雖然不是編譯器的專家,姑且讓筆者事後諸葛一下。

    某種程度上來說,Nim 不流行其實是非戰之罪。對於目標市場相近的產品,背後的團隊還是會造成微妙的影響。和 Nim 目標市場相近的語言有 Go (golang) 和 Rust,Go 來自 Google,Rust 來自 Mozilla,而 Nim 的團隊是誰呢?說實在的,相對沒那麼知名。專案的開發團隊不僅僅代表著名氣,某種程度也代表可投入的資源。像 Go 在語言特性上除了 goroutine 等共時性相關的語法外,其實沒有很突出,但 Go 在簡單及效能上做了很好的取捨,也寫了一套強大的標準函式庫,讓程式設計者有足夠的積木可以繼續堆出新玩具,正向的循環就此產生。而 Nim 沒有這樣的效應產生。

    其實,Nim 不是一無是處,如果花一些時間把玩一下 Nim 語言,會發現這個語言的確有可取之處。基本上,Nim 就是 Pascal 和 Python (再加上其他相對冷門的語言) 的特性混合在一起的產物,比起用傳統的 C 語言,的確可以用高階許多的語法產出相對高效的程式。在 Nim 語法中,筆者最喜歡重載 (overloading) 的部分,如果設計得宜,可以寫出相當簡潔的 API。至於巨集 (macro) 就稍微複雜了點,用到的機會其實不多。

    不過,Nim 的設計上仍有一些可改進之處。有些讀者可能覺得 Nim 的語法看起來怪了點,但筆者認為寫一小段時間就可以適應。以筆者觀之,Nim 的物件系統的確有一些問題,Nim 的物件採單一繼承,這倒也無可厚非,Go 甚至無法繼承物件,只能嵌入物件;但是 Nim 卻缺乏多重繼承或等效的語法,這在撰寫程式時會覺得綁手綁腳。現代語言較少直接採用多重繼承了,通常都是用介面 (interface) 或 mixin 或 trait 等方式取代,即使像 Go 的物件比較簡單,也加入介面來彌補其不足;而 Nim 的問題在於缺乏官方的方案,目前大概先用 proc 的 tuple 或 template 頂著先,而這些資訊只能透過社群的部落格文章得知。

    Nim 的巨集比較複雜,而說明文件不太清楚;說實在的,筆者試著讀官方網站和 Nim in Action 中和巨集相關的部分,但還是無法有效地寫出可用的巨集。不過,巨集這類的功能本來就比較進階,平常在寫程式時不太會天天寫巨集,即使在其他語言也是如此。Nim by Example 最後一個例子就是用巨集寫 OOP 程式,但筆者自認為一般寫程式的人不會這樣繞一大圈去建一堆 boilerplate code 後才去寫物件,這些東西應該要由開發團隊幫我們寫好才是。

    Nim 編譯器的錯誤訊息也有一些問題,某種程度造成學習的困難。剛開始寫 Nim 程式時,往往無法第一時間猜出錯誤訊息所要表達的意思;由於 Nim 是一個相對冷門的語言,即使試著 google 也要稍微猜一下才知道這些錯誤訊息是什麼意思;雖然在寫一段時間 Nim 程式後可以逐漸適應 Nim 編譯器的錯誤訊息,但這一來一往的過程可能就會趕跑一些潛在的使用者。像 Rust 的編譯器是龜毛出名的,但是 Rust 編譯器的錯誤訊息就很明確,Rust 開發團隊甚至做了網頁來補充說明每個錯誤代碼背後所代表的意義,讓使用者有足夠的訊息來除錯。

    Nim 的套件,不論是標準套件庫、官方出版第三方套件還是社群套件,也是 Nim 相對較弱的一環。觀察 Nim 的套件,似乎沒有一個明確的目標市場,有 GUI 套件 (nim-lang/gtk2)、網頁框架 (dom96/jester)、遊戲框架 (zengine),以及一些其他的套件。從這些套件看起來,Nim 像是一個通用型程式語言,但卻沒有足以吸引程式設計者轉枱的點;如果去把玩一下,說明文件也是相對稀少。像 Go 很明確地就是用在網頁及伺服器程式程式,Go 甚至沒有官方的 GUI 套件,很多領域也是放任社群自行發揮;但 Go 的確有滿足到某個特定領域,像中國許多的科技公司正在或已經將其後台轉到 Go。

    不論 Nim 或是其他新興編譯語言,開發環境總是會比較複雜。由於這些新興語言不太可能一夕間取代 C 的生態圈,往往都會透過 binding 的方式沿用 C 語言寫的函式庫。除了自身外,還要顧及 C 開發環境,專案的相依性就會變得更複雜。偏偏 Windows 又是對 C 不友善的平台,使得這個情形更加惡化,筆者曾撰文討論過這個問題,有興趣的讀者可看這裡。相較起來,雖然 Java 或 C# 的虛擬機器很肥,但這種模式的確大幅簡化專案的相依性需求;Java 平台除了無數的函式庫,上面還出現一大堆 JVM 語言,人們對 Java 平台的依賴程度又更深了,至少在這幾年內 Java 生態圈還是相當有市場的。

    Nim 的核心理念相當良好,但仍然有許多需要努力的地方。或許再過一段時間,Nim 和 Nim 的社群會更加成長,到那個時候,我們就可以看到更多 Nim 相關的應用。筆者最近開始發表 Nim 程式設計相關的文章,歡迎各位讀者到這裡觀看。