2022年 Stack Overflow開發者調查結果已經正式公布。每當這個時候,開發者們都有一肚子的話要吐槽或表揚,開發者 Adam Gordon Bell 也不外如是。Bell 最關注的是最受歡迎和最不招人待見的編程語言。我們先簡單看下調查結果:
- 最受歡迎的高人氣編程語言(2022):
Rust,Typescript,Python/ target=_blank class=infotextkey>Python,Go,C#,Kotlin,JAVAScript
- 最不受待見的高人氣編程語言(2022)
Ruby,C++,Java,php,C
為什么有的語言受歡迎、有的被討厭
在上一次開發者調查報告時,Bell 提到當人們喜愛一種新的編程語言時,大家或多或少會抱有些許偏見,即認為新語言應該拿來開發新項目、舊語言則用于開發舊項目。但這明顯忽略了另一個現實:語言工具本身也在不斷改進。因此,Bell 寫了一篇文章來論述了自己的觀點,并將編程語言被喜歡的原因歸結到了工具性發展上。
以 Go 和 Rust 為例,業界關于兩者的爭論從未停止,但兩種語言的開發者工具在體驗上非常相似:它們都非常現代,無論是測試、模糊測試、打包還是校驗,它們都能提供相應的最佳工具標準包。 Bell 認為,Go 和 Rust 跟不受待見榜單中那些語言的最大區別,并不在于語法細節,而是工具選項和生態系統。正是如此,二者才能雙雙進入最受喜愛語言名單。
Bell 認為,隨著時間的推移,編程語言的工具和開發者體驗正在改善,但這種改善在新語言中體現得更加明顯。總體來說,在創新成果出現之后,新語言會更快采用并加以標準化,最終提供超越老牌語言的效果。隨著這類增量的積累,曾經的王牌語言就會顯得陳舊而腐朽。
“為什么不能交個朋友?”
網友 “crashorbit”指出了實際開發中存在的問題。“大多數從事系統工作的人都是短期的承包商,他們不了解問題所在,并且在交付了一個測試不佳的系統后很快就離開了。可能忽略了版本控制、自動化測試、文檔更新、發布工程和預期的系統開發生命周期的其余部分。”
crashorbit 表示,中層管理者不懂系統工程,高級管理人員更感興趣的是“完成”事情,而不是擁有可持續的系統工程實踐。“坦率地說,我們很難區分一個設計良好的信息系統和一個基本可以工作但‘大風一吹’就會失敗的系統。”
每年從事“軟件工作”的人數都以幾個百分點的速度增長。他們中的大多數人在非常垂直的環境中工作,經常在自己的桌面上編寫電子表格或雜亂無章的應用程序。一些人編寫的“腳本”只是做簡單的事情。或者使用他們不理解的“機器學習”工具產生具有誤導性的結果。
“我們以這種方式創造即時遺產。沒有模塊化、沒有修訂控制、沒有部署策略,也沒有災難恢復計劃。開發人員早已不在,更不用說系統工程師了。這就是我所說的‘傳統阻力’的意思,這就是這個行業如此緩慢的原因。” crashorbit 表示。
開發者“fuddlesworth”表示自己所在的公司就已經被 React 16 “困住”,因為整個公司的核心 UI 組件都在使用 Enzyme 進行測試,一旦轉變就要改動成千上萬個測試。“我們不能再根據 React 來更新任何組件了,所以沒有 bug 修復、新特性、性能改進等等。”
開發者“alexiooo98”則認為,更好的工具當然非常受歡迎,但僅憑這個并不能完全解釋為什么有些語言受到喜愛,而有些則令人恐懼。比如,(現代)PHP 有很好的工具,但令人恐懼。Python 的包管理器環境非常混亂,然而 Python 很受歡迎。
下面是 Bell 文中關于編程語言發展差異的詳細描述,我們進行了翻譯并做了不改變原意的些許修改。請注意,下文中提到的創新跟語言的語法或語義無關。
標準庫
我不確定這到底是好事還是壞事,但擴展標準庫確實讓開發者無需安裝任何第三方庫,就能直接享受到 PHP、Python 和 Go 的大量現成功能。它們大部分都帶有 json、http 客戶端和服務器,甚至包括數據庫訪問機制。
——Amir Saeid
所謂標準庫,就是語言所附帶的常用內容庫。C 有 libc、C++有 libcpp,但與如今常見的內置“電池”標準庫相比,前面二位的庫規模實在小得可憐。
我有點記不清了,但 1991 年誕生的 Python 似乎是第一種真正擁有廣泛標準庫的編程語言。Java 1.0(1996 年)也附帶一個擴展標準庫(Java Class 庫),隨后引發其他語言紛紛效仿。
這種無需自行構建、又不必接觸第三方依賴項的便捷工具交付方式,實在是全世界開發者的一大福音。
標準庫中的佼佼者:GoLang
大部分現代語言(不包括 JavaScript )現在都附帶豐富的標準庫。不過,Go 對標準庫的強調仍然無人能及,它承諾向下兼容,而且非常關注性能和完善的具體實現。正因為如此,Go 開發者對標準庫的依賴性遠超其他社區,對標準庫也普遍更為重視。
第三方工具包庫
就在標準庫成形的同時,萬維網也開始迅速騰飛。事實證明,互聯網確實是一套出色的協作平臺。
如果我們的需求無法在標準庫中得到滿足、必須自行構建新功能,該怎么做?Perl 通過 CPAN 推廣了全球工具包集合的概念,一切就從那時起徹底改變。公平地講,任何用過 CPAN 并為它做出貢獻的朋友,都能感受到它改變游戲規則的重大意義。
CPAN 于 1995 年推出(基于 CTAN),并于 2003 年達到頂峰。它的出現為使用軟件完成工作的人們開辟出一條新的路徑,就是將第三方組件拼接起來。現在,很多現代開發項目都會遵循這種模式。
從 2003 年開始,之后誕生的常用編程語言幾乎全部附帶某種第三方工具包庫。這股風潮的締造者就是 CPAN,它告訴全世界:“真正的”編程語言,必須要有第三方工具包管理策略。
旁注:向后移植
說到這里,有朋友可能會問,既然 CPAN 讓 Perl 變得更好、也讓后來的新語言都接受了第三方工具包管理器這個概念,那為什么之前的語言就沒想著亡羊補牢、加上包管理器呢?
其實他們有想過,但語言的發展一旦經過特定階段,之后再想達成一致意見似乎變得越來越難。我不知道為什么會這樣,可能大多數人不喜歡做改變?
反正只要編程語言的習慣表達、基本模式和技術社區一旦建立,就很難再回頭調整了。正是因為這個,所以 JavaScript 有 NPC、Rust 有 crates,而 C++卻自己獨占 dds、cpm、conan、pacm、spakc、buckaroo、hunter 和 vcpkg。就是因為達不成普遍共識,所以 C++這邊才冒出了八種工具包管理器。
但標準庫的向后移植倒是比較順利,C++成功把一部分 STL 招至麾下,雖遲但到底完成了標準庫的添加。所以說,老語言也可以搭載工具創新,只是難度會更大一些。
總之,在 CPAN 之后,強大的標準庫已經能幫助開發者完成大部分任務。另外,易于使用且接受直接貢獻的第三方工具包庫也成了標配。沒有這兩樣,語言將毫無生命力。
文檔支持
有了第三方工具包,接下來就是用簡單的方式把它們記錄下來。我遇到的最早文檔版本就是 Javadoc。它讓我能更輕松地在 Java Class 中找到自己需要的內容:只需在 Web 上的 Javadocs 中單擊即可。之后,我們可以把 Javadoc 和 IDE 集成結合起來,快速使用自己之前從未見過的代碼。由此,探索性編碼成為了可能。
最強的文檔工具:Rust 的 docs.rs
如今,Java 的 Javadocs 已經不再是業界標桿。Go 有 godoc,Julia 有 Documeter.jl,就連 hackage 也有很好的工具包文檔。但縱觀天下,最強的文檔工具還要數 Rust 的 docs.rs。
一次編寫,隨處運行
我看到的一項改進是,J2EE 和 Web 服務器的標準化,成就了我們今天賴以生存的計算基礎。Java 與 JVM 雖然做出開創,但我覺得它們并沒得到充分的認可。在 Java 普及之后,開發平臺與部署平臺真正實現了互不干擾。如今每個人都習慣了這樣的優勢,但在 20 年前,這絕對是場革命性的顛覆。
——Cédric Beust
Java 和 JVM 確實推動了跨平臺開發的一路前行。開發環境不再需要跟生產環境緊密匹配。使用 JVM,我們可以將內容編譯成 JAR,并隨意運行在任何安裝有 Java 虛擬機的環境當中。
后來的虛擬化和容器化進一步拓寬了隨處運行的道路,但 Java 確實是第一種支持這類隨處運行工作流的主要編程語言。
隨處運行中的最強者:Zig
Java 方法當然不是完美的,首先就是 JIT 代碼的啟動速度很慢,另外是無法輕松調用非 Java 編寫的代碼。GraalVM 聲稱能夠解決這些問題,但目前的主流趨勢仍然是提前交叉編譯。只要不包含 C 或 libc 依賴項,Rust 和 Go 就都能輕松實現隨處運行。
但目前隨處運行中的最強者似乎要數 Zig,它不僅能夠輕松完成 Zig 程序的交叉編譯,還能兼容由 Clang 或 GCC 構建的任何代碼。
工具包管理器
有語言就有編譯器,其中提供大量標記可用于靈活調用,但使用過程也是相當麻煩。所以出現了 Make 和 AUtotools 這類工具。而后來的第三方工具包生態系統,又讓復雜度提升了一個量級。為了解決問題,出現了 Maven 和 pip。但與之對應,我們又遇上了編譯器或運行時版本不統一的問題,于是不同的程序就需要匹配不同的工具包版本。Python 給出了自己的解決方案,就是 pipenv、妙手 ualenv 以及 conda 之類我壓根理解不了的東西。
所有這一切讓復雜度繼續提升,導致新用戶幾乎跟不上節奏。因此,新的語言開始嘗試把這些一切集中管理起來,簡化開發流程。
我想說,工具包管理和 LSP 是我編程職業生涯中見證過的,真正改變游戲規則的兩大重要因素。
——Ganesh Sittampalam
就像內置“電池”標準庫擴展了語言的定義一樣,現代工具包管理器也大大提高了開發者對于體驗的預期。這種擴展的優勢在于易上手、開發體驗更好,缺點就是軟件的打包、發布和構建會帶來相應成本。語言作者需要在工具中投入大量時間來解決這些問題。
工具包管理器中的最強者
我認為 cargo 的一大核心優勢,在于它與語言相伴而生。而以往的主動構建工具往往缺乏與整個平臺的全面集成。
——Robert Masen
工具包管理器正在迅速發展。所以只要舍得投入工程時間,我們就能顯著改善自己語言的上手和日常使用體驗。于是,新項目在這方面的投入與日俱增。
Rust 的 cargo 和 rustup 文檔在體量上已經基本看齊 rust book,而且就這還不足以涵蓋所有 cargo 插件。無論是輕松切換語言的編譯器版本、快速運行測試、執行代碼覆蓋與性能測試、獲取供應商代碼、生成說明文檔、校驗代碼還是修復校驗問題,這些以往存在于語言生態系統中的獨立工具,如今都成為 Rust 中的開箱即用功能。Go 的情況也差不多。可以想見,后續出現的新語言要想百尺竿頭更進一步,需要付出多少努力。
代碼格式化器
代碼格式化器早在 gofmt 之前就已經出現,就如同 CPAN 之前就已經出現了第三方工具包,但這一切的最終成熟需要等待一場顛覆社區標準的深刻變革。
例如,在 Go 之前出現的任何語言,都不可能像 Go 那樣實現幾乎 100%的樣式一致性。這是因為之前的語言必須兼容原有代碼,而 gofmt 則強制執行單一樣式,且不提供任何調整選項。Go 之后的語言當然也就站在巨人的肩膀上,于是 Rust(rustfmt)和 Zig(zig fmt)同樣采用強大的默認代碼風格與隨附的代碼格式化器,并由此建立起開發者體驗優勢。
其實可以聊的還有很多,包括運行時改進,其基本相當于對語言的直接改進。IDE、LSP、模糊支持和重構工具等,則把側重點放在了開發者這一邊。但受篇幅所限,我們不可能無限延伸下去。
也有一些在語言創造者眼中必將改變世界的成果,最終從未得到廣泛采用,或者只在某個特定領域擁有影響力。很明顯,Jupyter notebook 與 REPL 就是典型。它們在某些應用領域特別關鍵,但在其他領域卻毫無知名度。Smalltalk 基于圖像的方法和 Mathematica/Wolfram 語言的語言集成數據雖然極具特色,但也更加小眾。
總結
能幫助開發者順利完成工作的工具,已經是編程語言可用性中的重要組成部分。而工具本身也在持續變化,標準不斷提高。
整個過程基本就是:在出現新的開發者創新工具時,比較年輕的編程語言更有機會將成果融入自身生態系統,由此形成增量優勢。隨著時間推移,這些增量優勢會推動開發者體驗迎來質變。
于是乎,較新的語言可以用更明確、更精準的方法解決問題,而舊有語言則面臨大量相互矛盾的方法、甚至完全沒有可行的解決路線。所以,開發者們才會普遍認為,傳統編程語言工具發展進度緩慢。
原文鏈接:
https://earthly.dev/blog/programming-language-improvements/