Architecture Decision Record

Active theme: Light

← ตัวอย่างบันทึกการตัดสินใจ

ภาษาโปรแกรม

สารบัญ:

สรุป

ประเด็น

เราต้องเลือกภาษาโปรแกรมสำหรับซอฟต์แวร์ของเรา เรามีความต้องการใหญ่สองอย่าง: ภาษาโปรแกรมส่วนหน้าที่เหมาะกับเว็บแอปพลิเคชัน และภาษาโปรแกรมส่วนหลังที่เหมาะกับแอปพลิเคชันเซิร์ฟเวอร์

การตัดสินใจ

เราเลือก 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: ภาษายอดนิยมที่สุดสำหรับการดูแลระบบ เครื่องมือวิเคราะห์ยอดเยี่ยม เฟรมเวิร์กเว็บดี แต่ Google ทิ้งไปใช้ Go

  • Ruby: ประสบการณ์นักพัฒนาที่ดีที่สุดตลอดกาล เฟรมเวิร์กเว็บที่ดีที่สุด ชุมชนที่น่ารักที่สุด แต่ช้ามาก แพ็กเกจยากพอสมควร

  • Rust: ภาษาใหม่ที่ดีที่สุด เน้นนามธรรมศูนย์ เน้นการทำงานพร้อมกัน แต่ระบบนิเวศค่อนข้างเล็ก และมีข้อจำกัดโดยตั้งใจต่อการเร่งความเร็วของคอมไพเลอร์บางประเภท เช่น การเข้าถึงหน่วยความจำโดยตรงต้อง unsafe อย่างชัดแจ้ง

  • TypeScript: เพิ่มชนิดข้อมูลให้ JavaScript ทรานสไพเลอร์ยอดเยี่ยม นักพัฒนาให้ความสำคัญกับการย้ายจาก JavaScript เป็น TypeScript มากขึ้น การสนับสนุนอย่างแข็งแกร่งจาก Microsoft

เราตัดสินใจว่า VM มีชุดข้อแลกเปลี่ยนที่เรายังไม่ต้องการตอนนี้ เช่น ความซับซ้อนเพิ่มเติมที่ให้ความสามารถขณะทำงาน

เราเชื่อว่าการตัดสินใจหลักของเราขับเคลื่อนโดยสองข้อกังวลที่ครอบคลุมหลายส่วน:

  • สำหรับความเร็วขณะทำงานสูงสุดและการเข้าถึงระบบที่แน่นหนาที่สุด เราจะเลือก JavaScript และ C

  • สำหรับความเร็วขณะทำงานใกล้เคียงสูงสุดและการเข้าถึงระบบที่ใกล้เคียงแน่นหนาที่สุด เราเลือก TypeScript และ Rust

คำกล่าวถึงอย่างให้เกียรติตกเป็นของภาษา VM และเฟรมเวิร์กเว็บที่เราจะเลือกหากต้องการภาษา VM:

  • Clojure และ Luminus

  • Java และ Spring

  • Elixir และ Phoenix

นัยยะ

นักพัฒนาส่วนหน้าจะต้องเรียนรู้ TypeScript ซึ่งน่าจะเป็นเส้นโค้งการเรียนรู้ที่ง่ายหากประสบการณ์หลักของนักพัฒนาคือการใช้ JavaScript

นักพัฒนาส่วนหลังจะต้องเรียนรู้ Rust ซึ่งน่าจะเป็นเส้นโค้งการเรียนรู้ปานกลางหากประสบการณ์หลักของนักพัฒนาคือการใช้ C/C++ และเป็นเส้นโค้งการเรียนรู้ที่ยากหากประสบการณ์หลักคือการใช้ Java, Python, Ruby หรือภาษาที่จัดการหน่วยความจำให้ที่คล้ายกัน

TypeScript และ Rust ต่างค่อนข้างใหม่ หมายความว่าเครื่องมือจำนวนมากยังไม่มีเอกสารสำหรับภาษาเหล่านี้ ตัวอย่างเช่น ไปป์ไลน์ devops จะต้องตั้งค่าสำหรับภาษาเหล่านี้ และจนถึงตอนนี้ เครื่องมือ devops ที่เรากำลังประเมินไม่มีตัวอย่างเริ่มต้นสำหรับภาษาเหล่านี้

เวลาคอมไพล์ของ TypeScript และ Rust ค่อนข้างช้า ส่วนหนึ่งอาจเกิดจากความใหม่ของภาษา เราอาจต้องดูวิธีบรรเทาเวลาคอมไพล์ที่ช้า เช่น การคอมไพล์ตามต้องการ การทำงานพร้อมกันของการคอมไพล์ ฯลฯ

การรองรับ IDE สำหรับภาษาเหล่านี้ยังไม่แพร่หลายและยังไม่ใช่ชั้นหนึ่ง ตัวอย่างเช่น JetBrains ขาย IDE PyCharm สำหรับการรองรับ Python ชั้นหนึ่ง แต่ไม่ขาย IDE ที่รองรับ Rust ชั้นหนึ่ง แต่ JetBrains ใช้ปลั๊กอิน Rust ที่ให้การรองรับภาษา Rust ประมาณ 80% เมื่อเทียบกับการรองรับภาษา Python

ที่เกี่ยวข้อง

การตัดสินใจที่เกี่ยวข้อง

เราจะมุ่งสู่ตัวเลือกระบบนิเวศที่สอดคล้องกับภาษาเหล่านี้

ตัวอย่างเช่น เราต้องการเลือก IDE ที่มีความสามารถที่ดีสำหรับภาษาเหล่านี้

ตัวอย่างเช่น สำหรับเฟรมเวิร์กเว็บส่วนหน้าของเรา เรามีแนวโน้มจะตัดสินใจเลือกเฟรมเวิร์กที่มุ่งสู่ TypeScript (เช่น Vue) มากกว่าเฟรมเวิร์กที่มุ่งสู่ JavaScript ธรรมดา (เช่น React)

ข้อกำหนดที่เกี่ยวข้อง

ชุดเครื่องมือทั้งหมดของเราต้องรองรับภาษาเหล่านี้

ผลงานที่เกี่ยวข้อง

เราคาดว่าเราอาจส่งออกความลับบางอย่างไปยังตัวแปรสภาพแวดล้อม

หลักการที่เกี่ยวข้อง

วัดสองครั้ง สร้างครั้งเดียว เรากำลังให้ความสำคัญกับความปลอดภัยบางส่วนเหนือความเร็วบางส่วน

รันไทม์มีค่ากว่าเวลาคอมไพล์ เรากำลังให้ความสำคัญกับการใช้งานของลูกค้าเหนือการใช้งานของนักพัฒนา

หมายเหตุ

หมายเหตุใด ๆ ที่นี่