我喜歡編程語(yǔ)言。每種語(yǔ)言都有自己的特點(diǎn)。最近,我開(kāi)始糾結(jié)一個(gè)問(wèn)題:如果開(kāi)始自己的項(xiàng)目的話,我該用什么語(yǔ)言。
好多優(yōu)秀的編程語(yǔ)言
在閱讀此文之前,需要先說(shuō)明幾件事情。雖然在工作中大部分的時(shí)候我都用 Java、JavaScript 和 Ruby 來(lái)創(chuàng)建產(chǎn)品應(yīng)用,但我一直在學(xué)習(xí)新的語(yǔ)言和新的框架。我相信,語(yǔ)言和語(yǔ)言(或框架)特有的社區(qū)能給你帶來(lái)新的思想,這些思想早晚會(huì)有用處:函數(shù)式編程可以給你帶來(lái)許多面向?qū)ο蟮木幊讨R(shí),而全職從事 Rails 應(yīng)用可以給你許多測(cè)試的經(jīng)驗(yàn)(如果你寫測(cè)試的話)。但問(wèn)題是,如果你想學(xué)會(huì)所有每種語(yǔ)言的優(yōu)秀概念,那么最終會(huì)在各種優(yōu)秀的功能中迷失方向。
另一個(gè)關(guān)鍵點(diǎn)是,我一直在用控制臺(tái)。我使用電腦的絕大部分時(shí)間都是在用瀏覽器和控制臺(tái)。沒(méi)錯(cuò),我編程用的是 Vim。我喜歡沒(méi)有空值的類型系統(tǒng)(我喜歡可選類型),這種類型系統(tǒng)很強(qiáng)大。因此我不喜歡 Java 的類型系統(tǒng),但我用過(guò)的最新版本只是 Java 6,所以很有可能現(xiàn)在的情況不一樣了!Java 的類型系統(tǒng)正是我嘗試 Ruby 的原因,因?yàn)?Ruby 社區(qū)總是在談?wù)撍麄兣c Java 的區(qū)別。聽(tīng)上去就像是,如果我寫 Java 代碼,我實(shí)際上是在幫助編譯器干活,而不是編譯器幫我干活。
我想說(shuō)的最后一件事就是我在尋覓的語(yǔ)言可能并不是你在尋找的語(yǔ)言!這篇文章里我會(huì)介紹一些我在最近幾個(gè)月在工作和個(gè)人項(xiàng)目中用過(guò)的語(yǔ)言。
Ruby
我很喜歡 Ruby。Ruby 是個(gè)非常強(qiáng)大的描述性語(yǔ)言,有許多成熟的函數(shù)庫(kù)(稱為“寶石”——gem),它們能幫你快速建立應(yīng)用。Rails 已經(jīng)非常成熟,非常容易使用。測(cè)試在社區(qū)的融入程度比任何其他語(yǔ)言都要深。Ruby 是個(gè)純粹的面向?qū)ο笳Z(yǔ)言,所以不管你使用什么函數(shù)庫(kù),大多數(shù)代碼都有相同風(fēng)格的 API,即類的 API。社區(qū)也很強(qiáng)大,Ruby 的開(kāi)發(fā)者似乎會(huì)給已有的函數(shù)庫(kù)貢獻(xiàn)代碼,而不是每次都編寫自己的函數(shù)庫(kù)(比如廣為流傳的 ActiveRecord 和 Sequel 就是很好的例子)。這種共識(shí)幫助人們擴(kuò)展函數(shù)庫(kù),其中的例子之一就是 Rails Admin 的 gem。
在速度方面 Ruby 并不是最快的。部署通常很重,需要很長(zhǎng)時(shí)間才能加載。使用 Ruby 很愉快,但在現(xiàn)實(shí)中,運(yùn)行 Rails 應(yīng)用需要很多時(shí)間和很多成本,特別是在 Heroku、AWS ECS 等“無(wú)服務(wù)器”的容器平臺(tái)上,因?yàn)樗加迷S多內(nèi)存、磁盤空間、流量和啟動(dòng)時(shí)間,而這些都要額外花錢。在本地運(yùn)行 Rails 完全沒(méi)問(wèn)題,Bundler 也很好用,但有時(shí)候它的“熱重載”機(jī)制會(huì)出問(wèn)題。
JavaScript
我也喜歡 JavaScript。絕大多數(shù)前端工作都是在 Web 上,因?yàn)槊總€(gè)人都有瀏覽器,所以發(fā)布很容易。所以使用其他語(yǔ)言似乎是件很奇怪的事情:“能招一個(gè)人為什么要招兩個(gè)?”JavaScript 也很容易學(xué)習(xí),而且因?yàn)樗鱾魃鯊V、易于上手,所以使用 JavaScript 基本不會(huì)有錯(cuò)。使用這個(gè)簡(jiǎn)單的語(yǔ)言實(shí)現(xiàn)原型非常容易,你可以直接啟動(dòng) node 命令行環(huán)境,或者直接打開(kāi) devtools!它們非常好用,任何開(kāi)發(fā) web 的人知道它們,所以你有很多開(kāi)發(fā)者!太好了。
難怪這是我們 Wix 使用的主要語(yǔ)言。
但是,JS 也有問(wèn)題。npm 模塊的狀態(tài)與 JS 的狀態(tài)不一樣,在類型系統(tǒng)方面社區(qū)有分歧(Flow vs. TS),函數(shù)庫(kù)和其他東西也是。我也有自己的喜好,所以……我覺(jué)得我也是社區(qū)的一部分。這種缺乏“社區(qū)精選”的結(jié)果就是雖然 npm 上有很多模塊,但很多模塊都不成熟。我?guī)啄昵皩戇^(guò)一篇文章,講述的是我在完全使用 JavaScript 幾年后又轉(zhuǎn)回 Ruby 的故事。我稱之為“倒退”。
Swift
最近我開(kāi)始學(xué)習(xí) Swift 進(jìn)行 iOS 開(kāi)發(fā)。之前我對(duì)它的了解為零,因?yàn)槲伊私獾囊磺卸贾皇窃鯓觿?chuàng)建 React 應(yīng)用。雖然這沒(méi)什么問(wèn)題,但我想嘗試些新東西。
Swift 是個(gè)靜態(tài)類型的編譯語(yǔ)言。它最初被用于 Apple 生態(tài)環(huán)境下的應(yīng)用程序開(kāi)發(fā),但它是開(kāi)源的,現(xiàn)在也可以用來(lái)開(kāi)發(fā) Linux 上的可執(zhí)行文件。我知道的最多產(chǎn)的一名 npm 作者 Sindre Sorhus 說(shuō)他想做更多 Swift 的工作。我完全理解他!Swift 的快速啟動(dòng)時(shí)間和好用的編譯過(guò)程可以保證運(yùn)行時(shí)的錯(cuò)誤越來(lái)越少。而且它沒(méi)有 NULL 值,但是卻有 Optional 類型。在 throw 之前必須明確聲明函數(shù)會(huì) throw 的內(nèi)容,但并不是像 Java 那樣通過(guò) throws 聲明進(jìn)行,而是有個(gè)非常巧妙地語(yǔ)法糖,就像是“try 一下,如果萬(wàn)一失敗還有 optional”。模式匹配通過(guò)與 Swift 枚舉類型的完美配合,變得非常強(qiáng)大。它還有類型推斷,雖然在方法定義中不能使用,但我覺(jué)得應(yīng)該問(wèn)題不大。真是個(gè)完美的語(yǔ)言!
但為什么 Swift 不是我的最終選擇?因?yàn)?Swift 只適合在 XCode 中使用。通常我使用 Vim,用別的編輯器會(huì)覺(jué)得效率很低。我嘗試過(guò) VSCode 和 Atom,但都不太好。也許,最終我會(huì)寫一個(gè) Swift CLI 工具能幫我編寫編輯器插件來(lái)改善開(kāi)發(fā)體驗(yàn),但至少現(xiàn)在這個(gè)東西還不存在。Swift 也沒(méi)有靜態(tài)編譯,所以你必須設(shè)置好 Swift 才能使用命令行程序。對(duì)于 Mac 應(yīng)用來(lái)說(shuō)這不是問(wèn)題,但在 Linux 服務(wù)器上,我希望編譯出的二進(jìn)制文件能包含一切。
ReasonML
我很喜歡這個(gè) Facebook 為 OCaml 做的嶄新語(yǔ)法。整個(gè)工具鏈感覺(jué)很成熟、很優(yōu)秀。OCaml 的包管理器 OPAM 自帶表情圖標(biāo),讓這個(gè)看上去很老的工具其實(shí)不是那么老。Merlin 和 OCaml/Reason 語(yǔ)言服務(wù)器也非常優(yōu)秀,而且能與 Vim 配合得很好。它還有個(gè)完美工作的自動(dòng)完成引擎(?。⑻D(zhuǎn)到定義、鼠標(biāo)懸停類型定義和更多的功能。優(yōu)秀的開(kāi)發(fā)工具從編輯器中分離,對(duì)于一門語(yǔ)言來(lái)說(shuō)這是非常好的。
Reason 可以用 BuckleScirpot 編譯成 JS,因此可以將 Reason/OCaml 代碼轉(zhuǎn)換成高性能的 JS 代碼。這非常好,因?yàn)檫@就相當(dāng)于 JS 也有了類型系統(tǒng),你還可以享受 JS 的函數(shù)庫(kù)。我很喜歡它。實(shí)際上,我唯一不喜歡的就是我得建立大量的類型定義才能使用依賴,但通常這并不是問(wèn)題:我們不需要對(duì)整個(gè)模塊建模,只需要對(duì)輸入、輸出和使用到的特定函數(shù)、類和方法建模即可。因?yàn)?Reason 并不是完全的函數(shù)式(有副作用),因此在我看來(lái), Reason 是最好的能編譯成 JS 的語(yǔ)言。
Reason 也能編譯成字節(jié)碼或原生代碼。使用純 OCaml/Reason 意味著只要編譯器通過(guò),就不會(huì)有運(yùn)行時(shí)的錯(cuò)誤,它也能靜態(tài)編譯,生成很小的二進(jìn)制文件,啟動(dòng)速度也很快。而且它編譯速度非??欤?/p>
在嘗試原生 Reason 應(yīng)用時(shí)我遇到的最大問(wèn)題就是我不知道別人在干什么,別人怎樣使用函數(shù)庫(kù)。大多數(shù)人都使用OCaml,但因?yàn)?OCaml 和 Reason 可以互換,所以我可以用 Chrome 擴(kuò)展把 OCaml 當(dāng)做 Reason 來(lái)閱讀。但依然不清楚。一些 OCaml 代碼不能轉(zhuǎn)換成 Reason,也許是因?yàn)?Chrome 插件中缺乏 PPX。據(jù)我的理解,PPX 是一種語(yǔ)法擴(kuò)展,基本上就是一些宏,將代碼從一種語(yǔ)法轉(zhuǎn)換成另一種語(yǔ)法??梢岳斫獬?Babel 插件或類似的東西。原生的 Reason/OCaml 不支持多核心,但要想實(shí)現(xiàn)并發(fā),可以使用 Lwt,這是個(gè)類似于 Promise 的庫(kù)。但我還沒(méi)找到哪怕一篇 Lwt 的指南或文章!
而且,似乎即使是原生 OCaml/Reason開(kāi)發(fā),入門的門檻也非常高,而且非常打擊積極性。社區(qū)不會(huì)解答問(wèn)題也不會(huì)分享知識(shí),絕大多數(shù)情況下都是要求提問(wèn)者去看源代碼或借口,但我相信最終這會(huì)改變,因?yàn)檫@只是 JS 開(kāi)發(fā)的開(kāi)始。
Golang
Go 是個(gè)非常好的語(yǔ)言。它很容易學(xué)習(xí),編譯和運(yùn)行都很快,還有 goroutine 和通過(guò) CSP 實(shí)現(xiàn)的簡(jiǎn)單并發(fā)。它支持多核心,而且可以編譯出靜態(tài)二進(jìn)制文件,能在最簡(jiǎn)潔的Linux上快速啟動(dòng)。它在變量定義時(shí)有類型推斷,但函數(shù)定義中沒(méi)有。它支持接口,看上去像是來(lái)自于有良好基礎(chǔ)的專業(yè)社區(qū)。
實(shí)際上,有很多很強(qiáng)大的模塊和應(yīng)用都是用 Go 寫成的,如 Docker、Kubernetes、CockroachDB,意味著你有可能將這些二進(jìn)制文件作為基礎(chǔ)設(shè)施的一部分,從而實(shí)現(xiàn)小型的、簡(jiǎn)單的分發(fā)(如在樹(shù)莓派上)。這一點(diǎn)非常強(qiáng)大。
在公用數(shù)據(jù)結(jié)構(gòu)(圖、樹(shù)等)和算法方面,它沒(méi)有泛型(也許下個(gè)版本就會(huì)加上了),我覺(jué)得這一點(diǎn)很奇怪:你必須每次都編寫同樣的代碼,或者使用代碼生成,雖然也能用,但我更希望編譯器能幫我完成這一切。而且,我并沒(méi)有完全理解它的模塊系統(tǒng) VGO,但我猜測(cè)隨著社區(qū)對(duì)之越來(lái)越熟悉,以后會(huì)有更多的信息和更簡(jiǎn)單的指南。最后一點(diǎn)個(gè)人意見(jiàn),我認(rèn)為語(yǔ)言本身不太干凈。我知道,這并不是不使用某個(gè)語(yǔ)言的理由,但至少我不會(huì)完整地測(cè)試它,或者在個(gè)人項(xiàng)目中使用它。Go 語(yǔ)言本身并不有趣。它很簡(jiǎn)單,很無(wú)聊,很好。我相信最后我會(huì)在某個(gè)正式系統(tǒng)中使用并愛(ài)上它。人的口味會(huì)變化!
Crystal
這篇文章以 Ruby 開(kāi)始,那么我們以 Crystal 結(jié)束吧。
Crystal 是另一門非常新的語(yǔ)言,它還沒(méi)到 1.0 版本??瓷先ズ芟?Ruby,但它是編譯語(yǔ)言,有靜態(tài)類型,而且很快!它像 Ruby 一樣支持 OOP,而且有很多很不錯(cuò)的功能,如類型推斷、optinoal 類型、用于并發(fā)的 CSP 和編譯時(shí)宏,有點(diǎn)像 Golang 的 codegen,但它的編譯器本身就支持。Crystal 有幾個(gè)新的 Web 框架,比如 Lucky 和 Amber。還有 Kemal,雖然它是 Sinatra 的,但也可以用在 Crystal 上。還有 ORM,而且由于 Crystal 重構(gòu)了 Ruby(用 Elixir 做了些修飾),你會(huì)發(fā)現(xiàn)它的 ORM 的 API 與 Ruby 幾乎相同,而且還有類型安全。這個(gè)非常重要!
由于這個(gè)語(yǔ)言還非常年輕,所以它還需要一段時(shí)間才能用于產(chǎn)品。我喜歡 Crystal 的并發(fā),它能使用所有的核心,就像 Go 語(yǔ)言一樣,但 Crystal 不需要手動(dòng)去 fork。我還喜歡它拋出異常會(huì)返回 result 類型,這樣錯(cuò)誤處理可以明確進(jìn)行了。我希望枚舉能有自己的值,這樣就能像 Swift 和 OCaml 一樣使用了。更好的編輯器支持也是必要的,自動(dòng)完成、鼠標(biāo)懸停類型提示都非常有用。此外,使用 Scry 可以使語(yǔ)言服務(wù)器的自動(dòng)完成用于標(biāo)準(zhǔn)庫(kù),但無(wú)法用于用戶自己的代碼。我還有點(diǎn)擔(dān)心 Crystal 不會(huì)到達(dá)發(fā)布 1.0 的那一天,但我真心希望它能發(fā)布。
可能你也看出來(lái)了,我希望未來(lái)的編程語(yǔ)言能夠吸取 Crystal、Go 和 ReasonML 的優(yōu)點(diǎn)。我不確定我喜歡哪種,但我覺(jué)得這些都是候選。我覺(jué)得我只需要等待,看看這些語(yǔ)言在未來(lái)幾個(gè)月或幾年會(huì)變成什么樣子。
-
JAVA
+關(guān)注
關(guān)注
19文章
2946瀏覽量
104372 -
編程語(yǔ)言
+關(guān)注
關(guān)注
10文章
1921瀏覽量
34506
原文標(biāo)題:我為何要棄 Java、JavaScript、Ruby 于不顧,而去尋找新的編程語(yǔ)言?
文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論