這篇文章,原標題是These Modern Programming Languages Will Make You Suffer,作者Ilya Suzdalnitski在文章中針對15種編程語言展開了詳細測評,希望對你有所幫助。

懶人目錄

概述篇:編程語言最重要的特徵

一星篇:C++,JAVA

二星篇:C#,Python,Rust,TypeScript

三星篇(上):Go,JavaScript

三星篇(下):Haskell,OCaml,Scala

四星篇:Elm,F#

五星篇:ReasonML,Elixir

ReasonML

ReasonML是一門最終會被編譯成JS語言的函數式語言,它主要應用在web前端開發中。ReasonML不是一門新語言,它是OCaml(一種古老而久經考驗的編程語言)的新語法。ReasonML由Facebook提供支持。

通過利用JavaScript生態系統,ReasonML沒有OCaml同樣的缺點。

所屬的編程語系:ML

👍不是JS的超集

ReasonML的語法和JS類似,這使得使用過JS的人很容易上手ReasonML。但是,不像TypeScript,ReasonML並不是JS的超集,也沒有繼承JS數十年來積累的一些糟糕設計。

👍學習時需要付出的代價

因爲ReasonML不準備成爲JS的超集,所以這門語言比JS簡單很多。任何有過用JS進行函數式編程經驗的人,都可以在差不多一週之內上手ReasonML。

ReasonML真的是這裏提到的最簡單的編程語言之一了。

👍函數式,但非純函數

不像Elm,ReasonML甚至不準備成爲一門純的函數式語言,也沒有“永不出錯”的目標,這意味着ReasonML非常實用,並且專注於開發者生產力,能很快地實現結果。

👍👍類型系統

ReasonML就是OCaml,這意味着它的類型系統幾乎和Haskell一樣好,ReasonML類型系統最大的缺點是,缺乏類型類,不過它支持函子(更高階的模型)。

ReasonML是靜態類型的,它的類型推論幾乎和Haskell一樣好。

👍👍生態系統

不像TypeScript,ReasonML已經獲取了整個JS生態系統。

👍JS/TypeScript互操作

ReasonML編譯成純JS,因此可以在同一個項目中同時使用ReasonML和JS/TypeScript。

👍ReasonML與React——絕配

如果你正在進行web前端開發,那麼你就有機會使用React了。你是否瞭解,React最開始就是用OCaml寫的,然後才被移到JS上來幫助採用?

因爲ReasonML是靜態類型的,所以無需擔心PropType。

還記得JS測評部分那個看上去無害但是卻導致了性能災難的例子嗎?

ReasonML對於不可變性數據結構有合適的支持,這樣的代碼不會造成性能問題:

id: “0”,

firstName: “John”,

}

friends=[samantha, liz, bobby]

onClick={id => Js.log(“clicked ” ++ id)}

/>

與JavaScript不同的是,當使用ReasonML時,沒有任何東西會得到不必要的重新呈現,非常好的開箱即用的React性能。

👎工具

ReasonML幾乎不像它的替代語言們那樣成熟(比如TypeScript),它在工具方面有一些問題。舉個例子,官方推薦的VSCode擴展推論語言服務器目前已損壞,不過還有其他替代品。

ReasonML在底層使用了OCaml編譯器,而OCaml以非常糟糕的編譯器錯誤消息而“臭名昭著”。雖然這不是致命的缺陷,但還是有點令人沮喪,並可能影響開發人員的生產力。

我希望隨着這門語言變成熟,它的相關工具能夠有所改進。

👍空值

ReasonML沒有空引用,它用Option模塊來表示可能不存在的值。

👍不可變性

ReasonML爲不可變性數據結構提供了一流支持。

👍模式匹配

ReasonML有很好的模式匹配支持。

結論

ReasonML可能就是TypeScript想要實現的結果,只不過TypeScript失敗了。ReasonML在JS的基礎上增加了靜態類型,同時刪除了所有糟糕的特徵(並增加了真正重要的現代特徵)。

最佳前端語言獎

ReasonML獲得了“最佳前端語言獎”。毫無疑問,ReasonML是web前端開發最好的選擇。

Elixir

Elixir可能是世界上最受歡迎的函數式編程語言了。和ReasonML一樣,Elixir並不是一門真正的新語言。Elixir是在Erlang三十多年的成功之上建立的。

Elixir是Go的函數式表親。和Go相似,Elixir最開始就專注併發性來設計,這是爲了利用多核處理器的優點。

和一些其他函數式語言不同的是,Elixir非常實用。Elixir專注於結果,我們不會在Elixir社區看到很多學術討論,Elixir論壇上充滿了實際問題的解決方案,這個社區對新手特別友好。

所屬的編程語系:ML

👍👍生態系統

Elixir的閃光點在於它的生態系統。在大多數其他編程語言中,語言和生態系統,是兩個獨立的東西。而在Elixir中,生態系統中的核心框架是由核心Elixir團隊開發的。

José Valim是Elixir語言的設計者,也是Phoenix和Ecot——Elixir生態系統中兩個超級酷的庫——的主要貢獻者。

在絕大多數其他語言中,有多個不同的庫專注同一個任務——許多不同的web服務器,許多不同的ORM等等。在Elixir中,開發需要專注於一些核心的庫,因此庫的質量也非常高。

Elixir庫的文檔特別好,有許多例子。不像一些其他語言,Elixir的標準庫也有很多相關文檔。

👍Phoenix框架

Phoenix框架的口號是“Phoenix感覺剛剛好”。與其他語言中的框架不同,Phoenix有很多內置功能。它開箱即用,支持WebSocket、路由、HTML模板語言、國際化、JSON編碼器/解碼器、無縫ORM集成(Ecto)、會話、SPA工具箱等等。

Phoenix框架因強大的性能而出名,它能夠在一臺機器上處理數百萬個同步連接。

👍全棧Elixir

Phoenix框架最近引入了LiveView,它允許在Elixir中建立豐富的實時web接口(對比單頁應用程序)。不需要JS,也不需要React!

LiveView甚至可以負責同步客戶端和服務器狀態,這意味着我們不必爲REST/GraphQL API的開發和維護操心。

👍數據處理

當處理很多和數據處理相關的任務時,Elixir是Python的可靠替代品。在用Python和Elixir構建了一個網頁數據抓取工具之後,對比發現,Elixir對於這個任務,是一門更好的語言和生態系統。

像Broadway這樣的工具允許在Elixir中構建數據攝入/數據處理管道。

👌類型系統

在我看來,缺少恰當的靜態類型是Elixir最大的缺點。因爲Elixir不是靜態類型,它的編譯器(以及dialyzer)會在編譯時報出很多錯誤。這和動態類型語言(比如JS, Python, 以及Clojure)有很大不同。

👍速度

Elixir編譯器是多線程的,提供了極快的編譯速度。與JVM不同,Erlang VM啓動速度很快。對於Elixir的用例來說,運行時性能非常好。

👍👍可靠性

Elixir是在Erlang之上創建的,Erlang花費了超過三十年的時間來創建世界上最可靠的軟件。一些在Erlang VM之上運行的程序能夠實現99.9999999%的可靠性。世界上沒有其他的平臺擁有同樣水平的可靠性。

👍👍併發性

大多數其他編程語言都不是爲併發性而設計的。這意味着,編寫使用多線程/多處理器內核的代碼遠不是一件小事。

其他編程語言使用執行並行代碼的線程(以及線程讀/寫入的共享內存)。這種方法通常容易出錯,容易出現死鎖,並導致複雜性呈指數級增長。

Elixir構建在Erlang之上,Erlang以其出色的併發特性而聞名,它採用了一種完全不同的併發方法,稱爲actor模型。

在這個模型中,進程(actor)之間沒有共享的內容。每個進程都保持各自的內部狀態,在不同進程之間通信的唯一方法是發送消息。

值得提及的是,正如它的創建者阿倫·凱(Alan Kay)最初所設想的那樣,actor模型實際上是OOP,它沒有任何東西是共享的,而對象只通過傳遞消息進行通信。

讓我們來快速對比Elixir和它命令式表親Go:

和Go不同,Elixir起初是爲了容錯率而設計的。當一個goroutine崩潰時,整個Go程序都會崩潰。在Elixir中,當一個進程掛掉時,只有這一個進程會掛掉,而不會影響程序的其餘部分。

更好的是,失敗的進程會由主管自動進行重啓。這允許失敗的進程重試失敗的操作。

Elixir進程也非常輕量,一個人可以輕鬆地在一臺機器上執行成千上萬個進程。

👍👍擴展

讓我們再和Go作一個比較。Go和Elixir中的併發性都利用了併發進程之間的消息傳遞。因爲Go編譯爲本機代碼,所以Go程序在第一臺機器上運行得更快。

但是,一旦你開始擴展到第一臺機器之外,Go程序就會開始輸掉比賽。爲什麼?因爲Elixir從一開始的設計就是可以在多臺機器上運行的。

Elixir運行的Erlang VM在分發和擴展方面非常出色。它可以無縫處理許多繁瑣的事情,如集羣、RPC功能和網絡。

在某種意義上,在微型服務真正面世的數十年前,Erlang VM就已經實現了微型服務。每個進程都可以被理解爲一個微型服務——和微型服務一樣,每一個進程都是獨立的。

在語言內置通信機制的情況下,進程在多個機器上運行是一件普遍的事情。

沒有Kubernetes複雜度的微型服務?仔細瞭解一下,你就會理解Elixir設計的真正目的。

👍錯誤處理

Elixir用特殊的方法進行錯誤處理。純函數式語言(Haskell/Elm)被設計出來是讓錯誤的可能性最小化,而Elixir則假設錯誤一定會發生。

在Elixir中,允許拋出異常,但是捕獲異常一般是不被鼓勵的行爲。進程主管會自動讓程序一直運行。

👌學習時需要付出的代價

Elixir是一門簡單的語言,新手可以花一到兩個月入門。使學習變得困難的是OTP。

OTP是Elixir的殺手級特性。OTP是一套來自Erlang的工具和庫,而Elixir是在Erlang基礎之上建立的。這是一種“祕方”,它大大簡化了併發和分佈式程序的構建。

雖然Elixir本身很簡單,但使用OTP設計Elixir系統會花上一點時間,至少對我來說是如此。

👍學習資源

作爲最受歡迎的編程語言,Elixir有着豐富的學習資源。這些學習資源往往對新手也很友好。

👍模式匹配

Elixir有很好的模式匹配支持。

👎數字處理

Elixir不能很好地處理計算密集型任務。編譯成本機語言的編程語言能夠更好地處理這些任務(比如Go/Rust)。

那Erlang怎麼樣?

對於企圖和目的,Elixir和Erlang的本質是相同的。Erlang是一種功能強大的語言,它的語法很奇怪。Elixir可以被認爲是Erlang的一種更好、更現代的語法(還有非常好的生態系統和社區)。

結論

Elixir可能是所有函數式語言中最成熟的,它也可以在爲函數式編程製作的虛擬機之上運行。Elixir最開始是針對併發性設計出來的,並且在多核處理器的現代社會中,它是最完美的搭配。

獎項

Elixir獲得了兩個獎項。

第一,它的彈性、函數優先的方法和驚人的生態系統使它成爲“構建web API的最佳語言”。

第二,OTP和actor模型使得Elixir成爲“構建併發和分佈式程序的最佳語言”。和命令式表親Go不同的是,用Elixir編寫的軟件能夠橫向擴展到成千上萬個服務器上,並且有開箱即用的容錯率。

寫在最後:在工作中使用正確的工具

       你會用螺絲刀錘釘子嗎?應該不會吧。那麼,我們也不應該試圖用一門編程語言完成所有任務,每一門語言都有它最合適的工作領域。

Go是最適合系統編程的語言。最適合前端開發的語言毫無疑問是ReasonML,它符合一門極好的編程語言的絕大部分要求。

Web API開發的冠軍絕對是Elixir,它唯一的缺點就是缺少靜態類型系統(這一缺點也因爲其良好的生態系統、社區、可靠性,以及併發特徵而抵消了)。對於任何類型的併發軟件/分佈式軟件,最好的選擇是Elixir。

如果你正在數據科學領域工作,那麼,非常遺憾的是,你只能選擇Python了。

文已至此,我衷心地希望,這篇文章能夠對你有所幫助。比較編程語言並不是一件容易的事,不過我已經盡力了。

 

相關文章