我為什麼要從 Python 轉向 Crystal 語言

我自 2011 年起,就是 Python 的用戶與愛好者了。當時,一個好友建議我用 Python 代替 Perl 試試 ,一個嶄新的世界向我開放了。在這個世界裡可讀性比什麼都重要,還有一種簡明的規則。

即使用了 7 年多的 Python ,我對它的熱情還是一如往昔。但是,歲月流逝之下任何人都該去追尋新的機遇與冒險。是時候嘗試下別的語言了!

Python 的問題

首先,列舉我在 Python 中遇到的一些問題:

  • 打包:這方面是大多數解釋型語言都會遇到的問題。打包成一個包括整個 virtualenv 的可安裝程序,FPM 之類的工具可以讓這個過程非常容易,但是它仍然缺少一個單一二進制程序的優雅。
  • 靜態類型:就像一些人從開始使用 C++ 到完全喜愛它,我確實懷念我在 C++ 中用過的類型安全。這與編譯時檢查密切相關,它確實幫助我們保證我們的代碼的質量,甚至在執行之前。
  • 速度:大多數解釋型語言的又一個問題。Python 對於許多任務都足夠快,但是仍然遠遠落後於編譯型語言。
  • 冗長:我們只有在 Python 3.6 才有 f-strings ,它確實是一個解脫。然而,我們在類和結構中仍然有非常冗長的 self 語法,到處都是 self.var = var ,這可能會在 Python 3.7 的數據類中部分解決。
  • 隱式私有類成員:我說的私有就是那該死的私有!作為一個前 C++ 程序員,我發現 Python 的私有屬性和方法的下劃線前綴格式有一點…變態?:‘)!

進一步來說,我不確定我真的喜愛 Python 在幾個領域的發展方向,尤其是在異步和類型方面。

  • 協程:儘管大受歡迎,Python 中新的異步方法讓人感覺非常不友好而且很難掌握。現有代碼在非阻塞之前也需要大量的工作。隨著越來越多的庫開放使用,以及隨著我瞭解且會使用新的庫越來越多,我覺得這種情況會隨之改善。
  • 類型註解(和 mypy ):說實話,類型註解很受歡迎…如果他們真的在 CPython 做了什麼的話。如果沒有主 CPython 發佈版本主流支持的情況下,使用類型註解作為各式結構體(如數據類)這種想法看起來毫無意義。與此同時,mypy 目前還不是主流,但長遠來看,作為一個 Python 類型校驗展示了巨大的潛能,特別是在將 --strict 標識開啟的時候。

我應該說明我仍然是 Python 的忠實粉絲和支持者,而且認為它仍然是當前最好的解釋型語言之一;特別是當你考慮到它驚人的生態系統和成熟度。

我在尋找什麼

我的出發點是 Python 和 Ruby 。 我經常在需要的地方使用 Ruby ,也非常喜歡它。 Ruby 解決了 Python 所具有的幾個問題(適當的私有/受保護的屬性,較少冗長的語法等等),但仍然存在性能問題,並且缺少靜態類型。

因此,我開始尋找具有以下特點的新語言:

  • 與 Python 和 Ruby 類似的語法
  • 單二進制分發
  • 編譯,靜態類型和快速
  • 面向對象(哦類,我多麼愛你......)

候選項

下列語言被排除在外

  • GO:沒有關鍵字參數、沒有異常、沒有類、沒有泛型以及命名風格的可怕,這些都導致我拒絕了Go(儘管也許這種簡單性吸引了很多人)。我實際上花了相當一段時間在 Go 的學習和編碼上,我覺得這是最令人沮喪的。在 C 之後,像 C++ 這樣的語言已經取得了很多進步,併為我們提供了更大的靈活性,但感覺 Go 似乎讓我們回到了 C 語言的時代。
  • Elixir:一種引人入勝的函數式語言,但缺少面向對象的功能,以及單個二進制分發不是此語言的目標的事實對我的用例來說有點失望。然而,我們團隊中的許多人將 Elixir 作為他們所有新項目的主要語言,並且發現它在使用中非常出色。Elixir 擁有豐富且可靠的傳統,如果你想要一種函數式語言,你一定要考慮它。
  • Rust:這是個有趣的語言,我花了一些時間嘗試學習。真的,我只是覺得 Rust 並不對症於我的用例。這是一種相當複雜的語言,我和其他很多人似乎都不喜歡它。
  • Julia:這種語言實際上是針對科學計算的,而不是我的用例。它也缺乏我想要的面向對象能力。
  • Pony:一種非常吸引人的語言,似乎借鑑了很多 Python ,但也借鑑了一些我不喜歡的東西(例如,強調前綴變量,缺乏對稱性等)。我大體上感覺 Pony 與我的想法不一致,認為它不具有與其他語言一樣的吸引力,這使得它現在相當原始。

我真正感興趣並希望在未來進一步研究的語言有:

  • Nim:Nim 是最初我準備用來領跑的下一個語言,我希望將來能花更多的時間來研究它。
  • Swift:另一種流行的面嚮對象語言,除了開發 iOS 和 Mac 應用程序外,絕對值得關注。

但是,最終,我決定致力於學習 Crystal !

原因如下:

  • Crystal 很快就能熟悉,因為它大部分遵循 Ruby 的語法
  • 它編譯成一個快速、單一的可執行文件
  • 整個標準庫都是用 Crystal 編寫的,可以在需要時很容易閱讀
  • 它提供了與 Ruby 類似的完全面向對象的方法(包括真正的受保護的和私有的成員)
  • Crystal 使用靜態類型,但也提供了聯合(能夠定義可以具有多種類型的變量)
  • 它提供了開發類似於 Ruby 的 DSL 的能力(這是我一直感興趣的)
  • 與 C 庫的綁定完全原生,並且以 Crystal 編寫(與 Python 中的 ctypes 類似,只不過更好)

注意事項

Crystal 是一個非常年輕的語言,仍然沒有發佈 1.0 版本。它通常會在版本中引入重大更改並且限制庫。

不過,我打算僅在我的個人項目中使用這種語言,並且願意成為早期使用者,因為我覺得這種語言有足夠的前景值得使用。

經驗

標準庫

整個標準庫非常容易閱讀,我一直在引用它。庫似乎也有一定的廣泛性,是一個很好的基礎教程。

以下是添加數組的示例:

我為什麼要從 Python 轉向 Crystal 語言

這裡是獲取文件擴展名的函數:

我為什麼要從 Python 轉向 Crystal 語言

如果你選擇嘗試 Crystal ,請確保讓它的源碼待在你身邊; 它非常有價值和有用。

綁定到 C 庫

這真的太神奇了!

下面是一個綁定從 Unix 系統獲取用戶信息的各種函數的例子:

我為什麼要從 Python 轉向 Crystal 語言

異常處理

類似的異常處理提供給 Puby 和 Python :

我為什麼要從 Python 轉向 Crystal 語言

寫你自己的異常很簡單;只需要集成 Exception 類。

導入系統和命名空間

這是來自 Python 的一些調整,但是因為 Ruby 遵循類似 C++ 的方法,把我帶回到了 C++ 時代。

C++ 命名空間等同於你可以自定義 Ruby/Crystal 模塊。要求任何庫將導入它定義的所有項目,因此它總是完美的保證了你的整個庫包含在模塊中,以此來避免命名空間汙染。

起初我還有點擔心,但我發現它可以從任意數量的文件中輕鬆建立一個模塊。然而,我得承認,找到事物的來源更像是一種挑戰。

我最喜歡的有關 Crystal 的部分是它如何處理實例變量的賦值:

我為什麼要從 Python 轉向 Crystal 語言

這將創建一個構造函數,它將自動用所提供的參數賦值給實例變量。Python 中的等價代碼是:

我為什麼要從 Python 轉向 Crystal 語言

雖然這涉及個人喜好,但我也非常喜歡 Ruby/Crystal 中 end 語句和兩個空格縮進的對稱性。我覺得它最終使得代碼閱讀起來更美觀而優雅。

當然,我們也有適當的 protected 和 private 成員以及抽象類;這兩個功能是我從我的 C ++ 時代就已經錯過的。

文檔

我非常喜歡 Crystal 的文檔。閱讀它是如此的愉悅。但與任何新的語言一樣,它可能是如其預期的那麼全面。

所提供的主要兩個文檔是:

  • Crystal Docs: 提供由該語言提供的大多數功能的非常愉快的概覽。一定要點擊屏幕頂部的小A圖標來調整字體、字體大小和主題(很好體驗)。我建議從這裡開始。
  • Crystal API 參考: 詳細介紹所有提供的模塊及其各自的類和函數。

另一個不錯的有用資源是 Gitter 上的 Crystal chatroom 。該頻道的每個人都非常熱心和樂於助人。到目前為止,他們一直是我探索旅程中的重要信息來源。

性能

雖然現在確定性能增益還為時過早,但做個 Fibonacci 測試總是很有趣的:)

Ruby/Crystal

我為什麼要從 Python 轉向 Crystal 語言

Python

我為什麼要從 Python 轉向 Crystal 語言

C

我為什麼要從 Python 轉向 Crystal 語言

用 -O3 編譯以獲得最佳性能。

C++

我為什麼要從 Python 轉向 Crystal 語言

用 -O3 編譯以獲得最佳性能。

Go

我為什麼要從 Python 轉向 Crystal 語言

結果

我為什麼要從 Python 轉向 Crystal 語言

總結

儘管現在是我和 Crystal 的相處早期,我仍舊樂觀地希望 Crystal 能儘快成為很多產品的選擇。我想 Crystal 能像 Python 和 Ruby 一樣順其自然的發展。

在不久的將來,留心那些關於 Crystal 的帖子,它們將包含我的技巧與訣竅。


分享到:


相關文章: