1. 程式人生 > >為何棄 Java、JavaScript、Ruby 於不顧,而去尋找新的程式語言?

為何棄 Java、JavaScript、Ruby 於不顧,而去尋找新的程式語言?

我喜歡程式語言。每種語言都有自己的特點。最近,我開始糾結一個問題:如果開始自己的專案的話,我該用什麼語言。

為何棄 Java、JavaScript、Ruby 於不顧,而去尋找新的程式語言?

好多優秀的程式語言

在閱讀此文之前,需要先說明幾件事情。雖然在工作中大部分的時候我都用 Java、JavaScript 和 Ruby 來建立產品應用,但我一直在學習新的語言和新的框架。我相信,語言和語言(或框架)特有的社群能給你帶來新的思想,這些思想早晚會有用處:函數語言程式設計可以給你帶來許多面向物件的程式設計知識,而全職從事 Rails 應用可以給你許多測試的經驗(如果你寫測試的話)。但問題是,如果你想學會所有每種語言的優秀概念,那麼最終會在各種優秀的功能中迷失方向。

另一個關鍵點是,我一直在用控制檯。我使用電腦的絕大部分時間都是在用瀏覽器和控制檯。沒錯,我程式設計用的是 Vim。我喜歡沒有空值的型別系統(我喜歡可選型別),這種型別系統很強大。因此我不喜歡 Java 的型別系統,但我用過的最新版本只是 Java 6,所以很有可能現在的情況不一樣了!Java 的型別系統正是我嘗試 Ruby 的原因,因為 Ruby 社群總是在談論他們與 Java 的區別。聽上去就像是,如果我寫 Java 程式碼,我實際上是在幫助編譯器幹活,而不是編譯器幫我幹活。

我想說的最後一件事就是我在尋覓的語言可能並不是你在尋找的語言!這篇文章裡我會介紹一些我在最近幾個月在工作和個人專案中用過的語言。

Ruby

我很喜歡 Ruby。Ruby 是個非常強大的描述性語言,有許多成熟的函式庫(稱為“寶石”——gem),它們能幫你快速建立應用。Rails 已經非常成熟,非常容易使用。測試在社群的融入程度比任何其他語言都要深。Ruby 是個純粹的面嚮物件語言,所以不管你使用什麼函式庫,大多數程式碼都有相同風格的 API,即類的 API。社群也很強大,Ruby 的開發者似乎會給已有的函式庫貢獻程式碼,而不是每次都編寫自己的函式庫(比如廣為流傳的 ActiveRecord 和 Sequel 就是很好的例子)。這種共識幫助人們擴充套件函式庫,其中的例子之一就是 Rails Admin 的 gem。

在速度方面 Ruby 並不是最快的。部署通常很重,需要很長時間才能載入。使用 Ruby 很愉快,但在現實中,執行 Rails 應用需要很多時間和很多成本,特別是在 Heroku、AWS ECS 等“無伺服器”的容器平臺上,因為它要佔用許多記憶體、磁碟空間、流量和啟動時間,而這些都要額外花錢。在本地執行 Rails 完全沒問題,Bundler 也很好用,但有時候它的“熱過載”機制會出問題。

JavaScript

我也喜歡 JavaScript。絕大多數前端工作都是在 Web 上,因為每個人都有瀏覽器,所以釋出很容易。所以使用其他語言似乎是件很奇怪的事情:“能招一個人為什麼要招兩個?”JavaScript 也很容易學習,而且因為它流傳甚廣、易於上手,所以使用 JavaScript 基本不會有錯。使用這個簡單的語言實現原型非常容易,你可以直接啟動 node 命令列環境,或者直接開啟 devtools!它們非常好用,任何開發 web 的人知道它們,所以你有很多開發者!太好了。

難怪這是我們 Wix 使用的主要語言。

但是,JS 也有問題。npm 模組的狀態與 JS 的狀態不一樣,在型別系統方面社群有分歧(Flow vs. TS),函式庫和其他東西也是。我也有自己的喜好,所以……我覺得我也是社群的一部分。這種缺乏“社群精選”的結果就是雖然 npm 上有很多模組,但很多模組都不成熟。我幾年前寫過一篇文章,講述的是我在完全使用 JavaScript 幾年後又轉回 Ruby 的故事。我稱之為“倒退”。

Swift

最近我開始學習 Swift 進行 iOS 開發。之前我對它的瞭解為零,因為我瞭解的一切都只是怎樣建立 React 應用。雖然這沒什麼問題,但我想嘗試些新東西。

Swift 是個靜態型別的編譯語言。它最初被用於 Apple 生態環境下的應用程式開發,但它是開源的,現在也可以用來開發 Linux 上的可執行檔案。我知道的最多產的一名 npm 作者 Sindre Sorhus 說他想做更多 Swift 的工作。我完全理解他!Swift 的快速啟動時間和好用的編譯過程可以保證執行時的錯誤越來越少。而且它沒有 NULL 值,但是卻有 Optional 型別。在 throw 之前必須明確宣告函式會 throw 的內容,但並不是像 Java 那樣通過 throws 宣告進行,而是有個非常巧妙地語法糖,就像是“try 一下,如果萬一失敗還有 optional”。模式匹配通過與 Swift 列舉型別的完美配合,變得非常強大。它還有型別推斷,雖然在方法定義中不能使用,但我覺得應該問題不大。真是個完美的語言!

但為什麼 Swift 不是我的最終選擇?因為 Swift 只適合在 XCode 中使用。通常我使用 Vim,用別的編輯器會覺得效率很低。我嘗試過 VSCode 和 Atom,但都不太好。也許,最終我會寫一個 Swift CLI 工具能幫我編寫編輯器外掛來改善開發體驗,但至少現在這個東西還不存在。Swift 也沒有靜態編譯,所以你必須設定好 Swift 才能使用命令列程式。對於 Mac 應用來說這不是問題,但在 Linux 伺服器上,我希望編譯出的二進位制檔案能包含一切。

ReasonML

我很喜歡這個 Facebook 為 OCaml 做的嶄新語法。整個工具鏈感覺很成熟、很優秀。OCaml 的包管理器 OPAM 自帶表情圖示,讓這個看上去很老的工具其實不是那麼老。Merlin 和 OCaml/Reason 語言伺服器也非常優秀,而且能與 Vim 配合得很好。它還有個完美工作的自動完成引擎(!)、跳轉到定義、滑鼠懸停型別定義和更多的功能。優秀的開發工具從編輯器中分離,對於一門語言來說這是非常好的。

Reason 可以用 BuckleScirpot 編譯成 JS,因此可以將 Reason/OCaml 程式碼轉換成高效能的 JS 程式碼。這非常好,因為這就相當於 JS 也有了型別系統,你還可以享受 JS 的函式庫。我很喜歡它。實際上,我唯一不喜歡的就是我得建立大量的型別定義才能使用依賴,但通常這並不是問題:我們不需要對整個模組建模,只需要對輸入、輸出和使用到的特定函式、類和方法建模即可。因為 Reason 並不是完全的函式式(有副作用),因此在我看來, Reason 是最好的能編譯成 JS 的語言。

Reason 也能編譯成位元組碼或原生程式碼。使用純 OCaml/Reason 意味著只要編譯器通過,就不會有執行時的錯誤,它也能靜態編譯,生成很小的二進位制檔案,啟動速度也很快。而且它編譯速度非常快!

OCaml工具鏈非常快!

在嘗試原生 Reason 應用時我遇到的最大問題就是我不知道別人在幹什麼,別人怎樣使用函式庫。大多數人都使用OCaml,但因為 OCaml 和 Reason 可以互換,所以我可以用 Chrome 擴充套件把 OCaml 當做 Reason 來閱讀。但依然不清楚。一些 OCaml 程式碼不能轉換成 Reason,也許是因為 Chrome 外掛中缺乏 PPX。據我的理解,PPX 是一種語法擴充套件,基本上就是一些巨集,將程式碼從一種語法轉換成另一種語法。可以理解成 Babel 外掛或類似的東西。原生的 Reason/OCaml 不支援多核心,但要想實現併發,可以使用 Lwt,這是個類似於 Promise 的庫。但我還沒找到哪怕一篇 Lwt 的指南或文章!

而且,似乎即使是原生 OCaml/Reason開發,入門的門檻也非常高,而且非常打擊積極性。社群不會解答問題也不會分享知識,絕大多數情況下都是要求提問者去看原始碼或藉口,但我相信最終這會改變,因為這只是 JS 開發的開始。

Golang

Go 是個非常好的語言。它很容易學習,編譯和執行都很快,還有 goroutine 和通過 CSP 實現的簡單併發。它支援多核心,而且可以編譯出靜態二進位制檔案,能在最簡潔的Linux上快速啟動。它在變數定義時有型別推斷,但函式定義中沒有。它支援介面,看上去像是來自於有良好基礎的專業社群。

實際上,有很多很強大的模組和應用都是用 Go 寫成的,如 Docker、Kubernetes、CockroachDB,意味著你有可能將這些二進位制檔案作為基礎設施的一部分,從而實現小型的、簡單的分發(如在樹莓派上)。這一點非常強大。

在公用資料結構(圖、樹等)和演算法方面,它沒有泛型(也許下個版本就會加上了),我覺得這一點很奇怪:你必須每次都編寫同樣的程式碼,或者使用程式碼生成,雖然也能用,但我更希望編譯器能幫我完成這一切。而且,我並沒有完全理解它的模組系統 VGO,但我猜測隨著社群對之越來越熟悉,以後會有更多的資訊和更簡單的指南。最後一點個人意見,我認為語言本身不太乾淨。我知道,這並不是不使用某個語言的理由,但至少我不會完整地測試它,或者在個人專案中使用它。Go 語言本身並不有趣。它很簡單,很無聊,很好。我相信最後我會在某個正式系統中使用並愛上它。人的口味會變化!

Crystal

這篇文章以 Ruby 開始,那麼我們以 Crystal 結束吧。

Crystal 是另一門非常新的語言,它還沒到 1.0 版本。看上去很像 Ruby,但它是編譯語言,有靜態型別,而且很快!它像 Ruby 一樣支援 OOP,而且有很多很不錯的功能,如型別推斷、optinoal 型別、用於併發的 CSP 和編譯時巨集,有點像 Golang 的 codegen,但它的編譯器本身就支援。Crystal 有幾個新的 Web 框架,比如 Lucky 和 Amber。還有 Kemal,雖然它是 Sinatra 的,但也可以用在 Crystal 上。還有 ORM,而且由於 Crystal 重構了 Ruby(用 Elixir 做了些修飾),你會發現它的 ORM 的 API 與 Ruby 幾乎相同,而且還有型別安全。這個非常重要!

由於這個語言還非常年輕,所以它還需要一段時間才能用於產品。我喜歡 Crystal 的併發,它能使用所有的核心,就像 Go 語言一樣,但 Crystal 不需要手動去 fork。我還喜歡它丟擲異常會返回 result 型別,這樣錯誤處理可以明確進行了。我希望列舉能有自己的值,這樣就能像 Swift 和 OCaml 一樣使用了。更好的編輯器支援也是必要的,自動完成、滑鼠懸停型別提示都非常有用。此外,使用 Scry 可以使語言伺服器的自動完成用於標準庫,但無法用於使用者自己的程式碼。我還有點擔心 Crystal 不會到達釋出 1.0 的那一天,但我真心希望它能釋出。

可能你也看出來了,我希望未來的程式語言能夠吸取 Crystal、Go 和 ReasonML 的優點。我不確定我喜歡哪種,但我覺得這些都是候選。我覺得我只需要等待,看看這些語言在未來幾個月或幾年會變成什麼樣子。

你最喜歡哪個語言?歡迎在下方留言分享你的想法。喜歡小編輕輕點個關注哦!