Architecture Decision Record

Active theme: Light

← 決策記錄範例

程式語言

目錄:

摘要

問題

我們需要為軟體選擇程式語言。我們有兩大需求:一門適合 Web 應用的前端程式語言,以及一門適合伺服器應用的後端程式語言。

決策

前端我們選擇 TypeScript。

後端我們選擇 Rust。

狀態

已決定。對出現的新備選方案持開放態度。

詳情

假設

前端應用是典型的:

  • 典型的使用者和互動

  • 典型的瀏覽器和系統

  • 典型的開發和部署

前端應用很可能會快速演進:

  • 我們希望確保快速、輕鬆的開發、部署、迭代等。

  • 我們重視可證明性,例如型別安全,並且願意為此多做一些工作。

  • 我們不需要遺留相容性。

後端應用的要求高於典型水平:

  • 對品質的目標高於典型水平,尤其是可證明性、可靠性、安全性等。

  • 對近實時性的目標高於典型水平,也就是說,我們不希望出現因虛擬機器垃圾回收造成的停頓。

  • 對函數語言程式設計的目標高於典型水平,尤其是在並行化、多核處理和記憶體安全方面。

我們接受較低的編譯速度,以換取編譯期安全性和執行時速度。

約束

我們對可用於主要雲服務提供商的函式服務(例如 Amazon Lambda)的語言有很強的約束。

立場

我們考慮了以下語言:

  • C

  • C++

  • Clojure

  • Elixir

  • Erlang

  • Elm

  • Flow

  • Go

  • Haskell

  • Java

  • JavaScript

  • Kotlin

  • Python

  • Ruby

  • Rust

  • TypeScript

論證

各語言總結:

  • C:因安全性低而被否決;Rust 幾乎在所有方面都能做得更好。

  • C++:因其混亂而被否決;Rust 幾乎在所有方面都能做得更好。

  • Clojure:建模能力出色;最接近的 Lisp 近似實現;在 JVM 上擁有出色的執行時。

  • Elixir:執行時出色,包括可部署性和併發;開發者體驗出色;生態系統相對較小。

  • Erlang:執行時出色,包括可部署性和併發;開發者體驗具有挑戰性;生態系統相對較小。

  • Elm:看起來非常有前景;IBM 正在釋出效果良好的重要案例研究;生態系統較小。

  • Flow:對 JavaScript 的有趣改進;然而,開發者正在逐漸放棄它。

  • Go:開發者體驗出色;併發出色;但有一系列嚴重削弱該語言的糟糕決策的記錄。

  • Haskell:最好的函式式語言;開發者社群較小;尚未取得足夠多已公開的生產環境成功案例。

  • Java:執行時出色;生態系統出色;開發者體驗欠佳。

  • JavaScript:有史以來最流行的語言;最廣泛的生態系統。

  • Kotlin:修正了 Java 的許多問題;有 JetBrains 的有力支援;有良好的從 Java 移植到 Kotlin 的公開案例。

  • Python:系統管理方面最流行的語言;出色的分析工具;良好的 Web 框架;但已被 Google 棄用而轉向 Go。

  • Ruby:有史以來最好的開發者體驗;最好的 Web 框架;最友善的社群;但非常慢;打包有些困難。

  • Rust:最好的新語言;強調零抽象代價;強調併發;然而生態系統相對較小;並且對某些型別的編譯器加速有刻意的限制,例如直接記憶體訪問需要顯式標記為 unsafe。

  • TypeScript:為 JavaScript 增加了型別;出色的轉譯器;開發者越來越重視從 JavaScript 移植到 TypeScript;有 Microsoft 的有力支援。

我們認為虛擬機器(VM)有一系列我們目前不需要的權衡,例如為提供執行時能力而帶來的額外複雜性。

我們認為,我們的核心決策由兩個貫穿性的關注點驅動:

  • 為了獲得最快的執行時速度和最緊密的系統訪問,我們會選擇 JavaScript 和 C。

  • 為了獲得接近最快的執行時速度和接近最緊密的系統訪問,我們選擇 TypeScript 和 Rust。

榮譽提名授予那些在我們想要選擇 VM 語言時會選用的 VM 語言和 Web 框架:

  • Clojure 和 Luminus

  • Java 和 Spring

  • Elixir 和 Phoenix

影響

前端開發人員需要學習 TypeScript。如果開發人員的主要經驗是使用 JavaScript,學習曲線可能比較容易。

後端開發人員需要學習 Rust。如果開發人員的主要經驗是使用 C/C++,學習曲線可能為中等;如果開發人員的主要經驗是使用 Java、Python、Ruby 或類似的記憶體託管語言,學習曲線可能較難。

TypeScript 和 Rust 都相對較新。這意味著許多工具尚未提供針對這些語言的文件。例如,DevOps 流水線需要為這些語言進行設定,而到目前為止,我們正在評估的 DevOps 工具都沒有針對這些語言的預設範例。

TypeScript 和 Rust 的編譯時間相當慢。其中一部分可能是由於這些語言較新。我們可能需要研究如何緩解緩慢的編譯時間,例如按需編譯、併發編譯等。

對這些語言的 IDE 支援尚未普及,也尚未達到一流水平。例如,JetBrains 銷售對 Python 提供一流支援的 PyCharm IDE,但沒有銷售對 Rust 提供一流支援的 IDE;相反,JetBrains 可以使用一個 Rust 外掛,它提供的 Rust 語言支援相對於 Python 語言支援大約為 80%。

相關內容

相關決策

我們將致力於做出與這些語言相一致的生態系統選擇。

例如,我們想選擇對這些語言具有良好支援能力的 IDE。

例如,對於我們的前端 Web 框架,我們更有可能選擇傾向於 TypeScript 的框架(例如 Vue),而不是傾向於純 JavaScript 的框架(例如 React)。

相關需求

我們的整個工具鏈必須支援這些語言。

相關製品

我們預計可能會將一些金鑰匯出到環境變數中。

相關原則

三思而後行(Measure twice, build once)。我們將一定的安全性置於一定的速度之上。

執行時比編譯時更有價值。我們優先考慮客戶的使用,而不是開發者的使用。

備註

此處填寫任何備註。