每日最新頭條.有趣資訊

每當我想放棄 Scala,我就寫寫 Python和Java

作者丨Li Haoyi

譯者丨平川

策劃丨趙鈺瑩

對於 Scala 的炒作在 2016 年達到了頂峰,此後這門編程語言的熱度不斷下降,甚至有人認為它已經進入了衰退期。實際上,Scala 的使用率近幾年一直在提升。相比 Java,使用 Scala 能將面向對象語言和函數式語言的優點相結合,用更少的代碼即可實現更高的性能;而相比 Python,Scala 雖然上手不那麽容易,但其性能和語言設計更強大,熟悉之後開發速度其實超過 Python。在很多資深程序員眼中,能替代 Java、並且能做得比它更好的只有 Scala。問題在於,Scala 未來是否能擴展新的用戶群體,變得不那麽“小眾”?

我的一位朋友最近在推特上表示:公眾對 Scala 編程語言的興趣似乎已經趨於穩定或減弱,這與我的感受一致。這篇博文將會討論為什麽會發生這種情況,並且聊聊 Scala 現在的地位以及 Scala 社區的未來。

本文最初發布於 Li Haoyi 的個人部落格,經原作者授權由 InfoQ 中文站翻譯並分享。

本文受下面這條推特啟發:

看到 Typesafe/Lightbend(注:Scala 的技術推廣公司)的朋友被解雇是一件很遺憾的事情,但正如我一直說的,免費的東西很難賣出去。

我很想知道 Scala 現在的採用情況。它沒死,但似乎在 2016 年就達到了熱度的頂峰。不過我沒有任何數據支持這個觀點。——Jamie Allen

Jamie 注意到,公眾對 Scala 編程語言的興趣似乎已經減弱了:對 Meetup 的興趣減少了,對會議的興趣減少了... 這或多或少跟我的觀察一致。儘管面向 Scala 愛好者的 Scala 專門會議仍然很熱門(或者說在新冠疫情之前,曾經很熱門),但我認為毫無疑問,在更廣泛的開發者社區中,關於 Scala 的討論的確越來越少。

我認為,公眾興趣減弱是客觀存在的事實,但任何新技術都會出現典型的“炒作周期”:

早期,Scala 掀起了一波宣傳熱潮,坦率地說,這甚至讓我感到驚訝:關於擴展語法邊界的宣傳,關於反應式架構的宣傳,關於函數式編程的宣傳,關於 Apache Spark 項目的宣傳。但自那以後,這種宣傳逐漸消失了,有一段時期,Scala 社區內外都出現了反對之聲。再然後,連反對的聲音也消失了,只剩下這種合理但乏味的語言,穩步地向前發展,為通用軟體工程提供了一個優秀的平台。

過熱期

雖然 Scala 最初創建於 2004 年,但直到 2010 年初它才真正開始起飛:

~2009:Twitter 開始將這門語言用於生產系統;

~2010:出現 Scalaz 函數式編程庫的第一個標記版本;

~2011:Scala 及相關技術推廣公司 Lightbend 成立;

~2014:使用 Scala 編寫 Apache Spark;

~2015:出現 Cats 函數式編程庫的第一個標記版本。

在此之前,Scala 社區非常活躍,上述這些關鍵節點是激發人們對這門語言興趣的主要里程碑。其中既有大規模的商業採用、商業支持,也有像 Apache Spark 這樣的大數據產品。所以公眾的興趣激增也就不足為奇了。Scala 社區的努力主要體現在以下幾個方面:

擴展語法邊界

早期,人們感興趣的是 Scala 語言的靈活性:它支持擴展方法、操作符重載、隱式構造函數 / 轉換,還有一個非常靈活的、可以以各種方式使用的隱式參數特性。這種靈活性是一種解放,因為它開啟了各種領域特定的語言和編程風格,這在其他語言中聞所未聞。

關於這一點,有許多項目可以證明,如 Databinder Dispatch HTTP 客戶端、Scala-Graph 數據結構庫或 SBT 構建工具:

// 發送一個HTTP請求,在Databinder Dispatch中處理輸出executer(:/(host, port) / target - { fromRespStr })

// 在Scala Graph中構造一個邊帶標簽的簡單有向圖val flights = Graph( (jfc ~+#> fra)(Flight("LH 400" ,10 o 25, 8 h 20)), (fra ~+#> dme)(Flight("LH 1444", 7 o 50, 3 h 10))

// 在使用SBT通過grep過濾後,將URL的內容追加到文件url("http://databinder.net/dispatch/About") #> "grep JSON" #>> file("About_JSON") !

// 使用SBT在源目錄中查找null的使用"find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !

許多這樣的庫從早期就已經發展起來了,並且已經轉向了更乏味的基於方法的 API。事實證明,命名操作符>- ~+#>或 #&& 雖然可行,但有時候這樣做並不是最明智的。不過,毫無疑問,使用操作符和領域專用語言來擴展 Scala 語法邊界是人們早期對於 Scala 的一大興趣點。

反應式架構

反應式架構主要由 Lightbend 通過其 Akka Actor 框架推動,是另外一項很大的工作。這種方法編寫的代碼與人們在學校裡可能學到的“普通”代碼差別很大,但是,它的高並發和高性能是用傳統風格編寫的代碼所無法達到的。

在最初的語法中,Akka Actors 犧牲了 Scala 的很多特性:actor 之間完全缺乏類型安全,禁止阻塞 API,以及許多其他特性。使用 Akka Actors 基本上是使用它們自己的語言,雖然嵌入在 Scala 中,但是有它們自己的約定、語法和語義。

最近,通過 Typed Actors 和 Reactive Streams,Akka 的開發體驗已經與傳統 Scala 編程的類型檢查體驗更接近了。我認為社區的態度也發生了轉變:不再將反應式架構視為解決所有問題的通用解決方案,而是將其視為解決某一類問題的一種可能的方法。這與我在自己的應用程序中使用這些技術的經驗基本一致。

函數式編程

關於 Scala 的函數式編程,最好的例子就是 Scalaz 和 Cats 項目。這兩個庫設法將 Haskell 中的很多函數式編程技術引入了 Scala 語言:重點關注 Monads 或 Applicatives 這樣的概念,避開語言面向對象的一面,採用更純粹的函數式風格。

這兩個庫的風格不同,並且都被社區的一部分人大量使用。在某種程度上,雖然布道已經停息,但是使用量仍然很大,每個人都認為函數式編程是編寫 Scala 應用程序的一種可能的風格。

Apache Spark

Apache Spark 是推動 Scala 早期發展的最後一個大項目。Apache Spark 是一個分布式大數據處理框架,它利用 Scala 的函數式風格和可序列化 lambdas 來獲取公共集合,如 map、filter 和 reduce,並在一個處理大量數據的計算集群上運行它們。與早期的 Hadoop API 相比,Apache Spark 讓我們編寫大數據處理管道的代碼少了幾個數量級,並且運行大數據處理管道的時間也少幾個數量級,因此 Spark 一炮而紅。

作為 Scala 的殺手級應用,Scala 社區中有很大一部分人使用 Scala 只是因為他們需要以某種方式與 Spark 進行互操作。

現在,Apache Spark 已經支持多種語言的開發 API:SQL、R,還有最為流行的 Python。起初類似於集合的 API 已經在很大程度上被更接近 SQL 的接口所取代,後者更好優化,對於經常使用大型數據集的 Apache Spark 來說,這是一個重要的因素。儘管如此,Apache Spark 代碼庫至今仍保留了大部分的 Scala。

低谷期

隨著最初的炒作逐漸平息,肯定會出現一些反對 Scala 的聲音。一些早期的貢獻者離開了社區,並且發生了一些人際關係的不愉快。不管是總體上,還是個人層面上:我自己認識許多人,他們厭倦了自己一直在宣傳的事情,心裡有點失望,可還得繼續前進。

很難確切地說炒作是何時消失的,可能在 2016-2018 年左右。

即使在技術層面上,也並非一切順利。雖然許多組織在各自的領域中成功地使用了這些技術,但是其他組織卻後悔將全部精力投入到 actor 和函數式編程中。他們發現,這些技術並不像他們所希望的那樣適合他們的問題,並且不得不花時間從他們對特定編程範式的全部投資中退出。據我所知,許多組織都被迫做出了這樣的調整。

早在 2010 年代初,我就對其中相關技術的炒作感到驚訝。在其中有些庫,操作符的使用非常廣泛,有時甚至會將簡單的任務變成複雜的腦筋急轉彎。對反應式架構和函數式編程的過度吹捧,與它們最適合的特定用例並不匹配:每一次 Scala 大會上都有主題演講者宣稱這兩種方法是軟體架構最重要的未來。

我一點也不驚訝,隨著時間的推移,其他人會像我一樣意識到其低谷期的來臨。

現狀:復甦期

Scala 在 2010 年代初被大肆吹捧,隨後在 2010 年代中後期這種炒作遭到強烈抵製。那麽 Scala 現狀如何?

一個穩步發展的社區

儘管公眾的興趣明顯下降,但 Scala 的使用率仍在繼續增加。我維護了許多開源庫,從 Maven Central 套裝軟體存儲庫下載這些庫的非重複 IP 的數量比去年增加了 2 倍多。雖然每個包的下載量或指標存在一些差異,但總體而言,它們非常符合這一趨勢。

雖然這種增長並不是部分人所期望的指數級增長,但這是一種使用量的穩步增長,符合我的主觀體驗:儘管炒作已經消失,但 Scala 的使用率仍在繼續增長。如果未來能保持每年 2 倍的增長,我詳細 Scala 社區將會繼續保持良好的狀態!

如果你看一下最近的 Redmonk 排名或 Tiobe 排名,就會發現 Scala 的排名穩定地徘徊在主流語言之外,分別排在第 13 位和第 28 位。不尋常,但也不難理解。

炒作和反彈都成了遙遠的記憶,現在看來,Scala 是一種支持多種編程風格的靈活語言,每一種風格都有自己的權衡和適用場景。早期的熱情和衝突已經轉變為人們使用 Scala 穩定地工作,享受他們自己選擇的語言。

一個可供生產應用的穩固平台

儘管天花亂墜的宣傳有所減少,但 Scala 語言比過去要好得多:

SBT 構建工具在過去幾年中有了質的改進:速度更快,使用更方便。

如果不喜歡 SBT,現在也有其他的選擇:許多組織將 Bazel 或 Pants 用於 Scala,而我自己的 Mill 構建工具也很穩定且應用廣泛。

像 Coursier 這樣的新工具正成為生態系統的一個新的基礎:從 Ammonite 到 SBT 再到 Mill 都在使用。

Metals 項目為 VSCode、Sublime Text 和任何其他支持語言伺服器的編輯器提供了 Scala 支持。

Intellij 自己的 Scala 插件也在不斷改進:更快、更準確,並且支持新的工具,比如 Ammonite 腳本或 Mill 構建工具。

Scala 2.13 中的新集合庫清除了大量舊有的缺陷,並在許多情況下顯著提高了性能(例如 Sjsonnet 速度提升 25-40%)。

“打磨”特性,如字元串模式匹配或警告抑製,繼續改善開發體驗。

編譯器本身的速度也大大加快,代碼編譯速度幾乎是三年前的兩倍。

雖然語言規範在過去幾年幾乎沒有任何變化,但是,已經實現的開發體驗改進非常之多。如果你在 2017 年與任何使用 Scala 的工程組織討論將編譯時間減半的問題,他們會給你一大筆錢讓你實現它!

上述所有改進都極大地改善了我自己編寫 Scala 的體驗,還有許多改進我無法在這裡一一列舉。

一個廣泛而多樣化的生態系統

雖然對於最初四項工作的宣傳已經減弱了,但它們仍然在 Scala 生態系統中形成了大量活躍的子社區。例如,雖然不是每個人都想使用純函數式編程,也不是每個人都想一直使用它,但是,與之相關的庫和生態系統卻是多種多樣,質量高且維護良好。當你遇到需要使用純函數式編程的場合時,你可以找到所需的一切。

在某種程度上,之前的宣傳達到了它的目的:通過向大量的人介紹一個特定的范例,使子社區的人數達到維持這個子社區發展的臨界數量。

我們可以將 Scala 中廣泛的風格看作是一種福利:不是將其視為分割社區的一種方式,而是將那些永遠不會相互交流的社區聚集在一起的一種方式。沒有 Scala,這些社區可能各自在 Haskell、Python、Java 和 Go 系統中工作,互不相乾。通過關注共享的內容而不是不同之處,Scala 讓這些社區在對所有人都有利的事情上協作,同時每個子社區仍然保持獨一無二。

我沒有默認使用 Actors 來設計代碼架構,但是我已經交付了大量使用 Actors 的生產代碼。我也沒有默認使用純函數式編程技術,但是我使用了一些非常深奧的結構,比如 Free Applicatives。我認為,社區作為一個整體也以類似的方式變得更加成熟了:欣賞不同的風格,並在適當的地方使用它們,沒有了早期困擾 Scala 的教條主義。

未來展望

那麽,Scala 未來還會有什麽令人興奮的東西嗎?

對我來說,Scala 語言本身處於一個相對良好的狀態。花一整個下午的時間編寫現代 Java 代碼就足以讓我擺脫“其他編程語言已經迎頭趕上 Scala”的想法,花了幾天時間嘗試(最終並未成功)將 Python 項目打包成一個獨立的可執行文件也是如此。

Scala 未來最大的潛力在於發展新的用戶群,以及尋找新的應用場景,到目前為止,這些都完全不在社區的考慮範圍內。但在我看來,有兩件事很重要。

易用性

在 Scala 最初的四項工作中,少了一樣東西:讓新晉開發人員能夠從代碼庫開始,並立即具備生產力。無論你使用的是 operator 為主的調度風格,還是 actor 為主的反應風格,還是 Cats/Scalaz 純粹的函數式風格,都一樣:每一個開始嘗試 Scala 的人都會遇到困難。

為什麽會這樣呢?

舉個相反的例子,開發人員通常覺得 Python 是一門很容易入門的語言:他們稱之為“可執行的偽代碼”。新程序員學 Python,非程序員學 Python。當人們使用記號筆在白板上編寫代碼時,他們編寫的通常也是 Python。雖然 Python 的性能、並發性或大規模可維護性存在問題,但它的易於入門是無與倫比的。

為什麽 Scala 不能像 Python 那麽容易上手呢?

回答這個問題是我維護這整套庫的目標。我的許多庫複製了 Python 中的同類庫。例如:

Ammonite 複製了 IPython REPL;

uPickle 複製了 Python json 模塊;

PPrint 複製了 Python pprint 模塊;

Requests-Scala 複製了 Kenneth Rietz 的 Requests 模塊;

OS-Lib 複製了 Python os、sys 和 shutil 模塊;

Cask 複製了 Armin Ronacher 的 Flask 庫。

事實證明,你可以讓 Scala 變得像 Python 一樣容易上手。而對於 Python 的所有弱點——性能、並發性、可維護性——Scala 已經做得很好了。Scala 完全有潛力成為既有 Python 的易用性和靈活性,又兼具 Java 或 Go 的性能和可伸縮性的編程語言,再加上遠遠超出了這些編程語言的類型安全可維護性,字面意義上的兩全其美。

雖然在某些情況下,高並發反應式架構或純粹的函數式編程是完成工作最好的工具,但我希望將來,開發人員將能夠以一種簡單明了的方式上手 Scala 語言,並且只在需要時才學習那些更高級的技術。

Scala Native

Scala.js 已經證明了在其他平台上使用 Scala 的可行性:編譯成 JavaScript 而不是在 JVM 上,JavaScript 擁有充滿活力的生態系統和社區,將 Scala 語言引入到瀏覽器,這是一個以前從未用過 Scala 的地方。

Scala-Native 帶來了更大的變革:通過將 Scala 編譯成自包含的二進製可執行文件,使得 Scala 語言可以在 JVM 或 JavaScript 運行時啟動時間和資源開銷不可接受的情況下使用。如果說 Scala.js 將 Scala 引入到了瀏覽器,Scala-Native 則有望將 Scala 引入更多新環境:

命令行工具,如 git、ls、rsync 等,它們無法忍受 JVM 的啟動時間;

Sidecar 進程或後台守護進程,其中 JVM 的大量記憶體開銷會使 Scala 的使用出現問題;

iOS 上的移動開發,iPhone 和 iPad 是世界上最普遍的消費類計算設備之一;

桌面應用程序,其中 JVM 啟動太慢或與 JVM 捆綁在一起太笨重;

與原生庫的深度集成,如 Tensorflow 機器學習框架。

傳統上,這類程序是用 C 或 C++ 等不安全的語言編寫的。最近的實現通常是用 Rust 或 Go 編寫,還有一些家庭作坊式的非 C 語言試圖填補這個空白,比如 Nim、Zig 或 Crystal。Scala-Native 有望填補這個空白,不是使用一種全新的語言,而是使用一種已經流行的語言,而且它已經有一個具備豐富的庫和工具的生態系統。

Scala-Native 要取得成功比 Scala.js 困難得多。Scala.js 可以專注於編譯器,然後將其委託給現有的 JavaScript 運行時,而 Scala-Native 必須根據基本原則構建自己的運行時:線程、垃圾收集、事件循環等等。這需要做大量的編譯方面的工作。但是,如果成功的話,這對於拓寬 Scala 語言的使用範圍將是一個巨大的福音。

小 結

雖然對於 Scala 語言的炒作在過去幾年裡已經逐漸平息,但它的使用率仍在穩步增長,使用體驗也在不斷改善。這正是你所期望的,因為一種語言在經歷了炒作周期之後,會從一個炒作驅動的社區發展成一個價值驅動的社區。Scala 開發人員並不是為了使用這門語言而使用,而是將其作為一種可靠的工具來實現與 Scala 無關的技術或業務目標。

實際上,這就是社區成熟的含義。

展望未來,我希望我們能看到更多這樣的情況,更多地關注結果和價值,而不是炒作,更多的權衡利弊,而不是教條主義,更多的鼓勵共享,而不是爭論分歧,以及實現更多像編譯器兩倍速提升的優化!

我認為,讓 Scala 社區增長 10 倍的方法,不是花 10 倍的精力去討論現有的語言語法,不是花 10 倍的精力去討論函數式編程和面向對象編程,也不是花 10 倍的精力去讓我們已經類型安全的代碼更加類型安全。相反,我們能應該通過包容性地擴展該語言,讓那些以前從未接觸過它的開發人員使用它:新手、非程序員、命令行工具人員、iOS 開發人員等等。如果我們看看 2019 年的 Jetbrains Python 開發者調查,我們就可以看到 Python 語言在不同領域的使用廣度:

目前,Scala 主要用於後台服務和 / 或 Spark 數據管道,但其實 Scala 還能用於很多其他的使用場景。Scala 社區要設法讓 Scala 的使用變得足夠簡單和廣泛,讓所有人(不僅僅是後台 / 數據工程師)都能學會 Scala 並使用它,同時享受 Scala 社區所熟知和喜愛的簡潔性、性能和類型安全。

參考鏈接:

http://www.lihaoyi.com/post/TheDeathofHypeWhatsNextforScala.html

為你推薦

InfoQ Pro是 InfoQ 專為技術早期開拓者樂於鑽研的技術探險者打造的專業媒體服務平台。

InfoQ Pro推出新人福利,掃描下方二維碼關注 InfoQ Pro,即可免費獲得InfoQ全套迷你書,機會難得,快來領取吧!

點個在看少個 bug

獲得更多的PTT最新消息
按讚加入粉絲團