- โครงการ Git ประกาศอย่างเป็นทางการว่า จากนี้ไปจะ นำ Rust มาใช้ในแกนหลัก และตั้งแต่ Git 3.0 เป็นต้นไป Rust จะกลายเป็น ข้อกำหนดบังคับสำหรับการบิลด์
- ชุดแพตช์ครั้งนี้ดำเนินไปในลักษณะของ การทดลองนำร่อง (test balloon) คล้ายกับการนำความสามารถ C99 มาใช้ในอดีต โดยมีเป้าหมายเพื่อค่อย ๆ วางโครงสร้างพื้นฐานสำหรับการนำ Rust มาใช้
- ในขั้นแรกได้แปลงโมดูล varint.c ที่แทบไม่มี dependency ไปเป็น Rust เพื่อทดสอบ การทำงานร่วมกันระหว่าง C-Rust และเครื่องมือสำหรับการบิลด์
- ขณะนี้รองรับเฉพาะการบิลด์ด้วย Meson เท่านั้น และในอนาคตมีแผนเพิ่ม การรองรับ Makefile รวมถึงเพิ่ม การตรวจสอบการบิลด์ Rust ใน CI และการตรวจสอบความสม่ำเสมอของรูปแบบโค้ดด้วย
cargo format
- นี่คือการเปลี่ยนแปลงสำคัญที่เปิดเวลาให้ชุมชน Git และผู้จัดทำแพ็กเกจได้ ปรับตัวกับข้อกำหนดใหม่ของ Rust toolchain พร้อมทั้งช่วยเพิ่มความปลอดภัยของโค้ดและความสามารถในการขยายในระยะยาว
ที่มาของการนำ Rust มาใช้
- Git ได้พิจารณาวิวัฒนาการด้านภาษาเพื่อความเสถียรและการบำรุงรักษา
- การนำ Rust มาใช้มีความหมายในแง่ของ การเสริมความปลอดภัยด้านหน่วยความจำ, การใช้ประโยชน์จาก toolchain สมัยใหม่ และ การเปิดทางสู่การปรับแต่งประสิทธิภาพ
- อีกทั้งยังต้องการสร้าง codebase ที่แข็งแกร่งยิ่งขึ้นผ่านการนำภาษาสมัยใหม่มาใช้
- การแจ้งล่วงหน้าว่าเมื่อถึงช่วงออก Git 3.0 จะต้องใช้ Rust เป็นการเปิดเวลาให้ ecosystem เตรียมความพร้อม
- จะค่อย ๆ ขยายขอบเขตการใช้โค้ด Rust ทีละขั้น และมีแผนสุดท้ายที่จะนำฟังก์ชันแกนหลักบางส่วนมาเขียนใหม่ด้วย Rust
ชุดแพตช์เชิงทดลอง
- เลือก varint.c เป็นโมดูลแรกสำหรับการนำ Rust มาใช้
- เรียบง่ายมากและไม่มี dependency
- สามารถตรวจสอบ interop ระหว่าง C ↔ Rust ได้
- ทดลองได้โดยไม่กระทบต่อฟังก์ชันโดยรวมของ Git
- การทดสอบทั้งหมดผ่านบนเวอร์ชัน varint.rs
การเปลี่ยนแปลงของระบบบิลด์
- ตอนนี้เพิ่มการรองรับ Rust เฉพาะใน ระบบบิลด์ Meson
- ในอนาคตมีแผนเพิ่ม การรองรับ Rust ใน Makefile
- ยังต้องเตรียมงานที่เกี่ยวข้องกับ CI ด้วย
- การตรวจสอบการบิลด์และการทำงานของ Rust
- การรักษาความสม่ำเสมอของสไตล์โค้ดผ่าน
cargo format
- เครื่องมืออื่น ๆ และการทำงานอัตโนมัติด้านการบำรุงรักษา
แผนในอนาคต
- งานครั้งนี้มุ่งเน้นที่ การทดลองกระบวนการนำ Rust มาใช้ มากกว่าฟีเจอร์ของ Rust เอง
- หลังจากนี้อาจมีการเขียนฟังก์ชันภายใน Git ด้วย Rust เพิ่มเติม รวมถึง โมดูล xdiff
- มีแผนค่อย ๆ ขยายการใช้ Rust เพื่อให้ ecosystem ทั้งหมดปรับตัวเข้ากับสภาพแวดล้อมการบิลด์ที่อิง Rust
นัยสำคัญ
- Git กำลังเตรียมพร้อมสำหรับการเปลี่ยนผ่านด้านภาษาที่สำคัญที่สุดครั้งหนึ่งในประวัติศาสตร์
- การกำหนดให้ Rust เป็นข้อบังคับจะช่วยเสริม ความปลอดภัย การบำรุงรักษา และศักยภาพการพัฒนาในระยะยาว
- สำหรับผู้จัดทำแพ็กเกจและนักพัฒนา ต่อไป การเตรียมสภาพแวดล้อมการพัฒนา Rust จะกลายเป็นสิ่งจำเป็นใน ecosystem ของ Git
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ลิงก์การอภิปรายที่เกี่ยวข้อง
และเพราะ Rust เป็นภาษาที่ยังไม่มีมาตรฐาน จึงสงสัยว่าเมื่อเวลาผ่านไป implementation อาจล้าหลังมากขึ้นได้ (เหมือนที่เคยเกิดกับ Java)
Git ดูเป็นเครื่องมือที่สุกงอมมากแล้ว น่าจะต้องการเพียงการบำรุงรักษาหรือปรับปรุงเล็กน้อยเท่านั้น ไม่ได้ดูเหมือนต้องมีโค้ดใหม่ขนาดใหญ่จนต้องนำภาษาใหม่เข้ามา
ต่างจากกรณีอย่าง Linux ที่ยังต้องมีไดรเวอร์ใหม่ ๆ อยู่เสมอ ซึ่งสำหรับ Git ดูไม่เห็นเหตุผลแบบนั้น
อยากให้มีคนอธิบายว่าตนกำลังมองข้ามอะไรไปหรือไม่
ดูการเปลี่ยนแปลงของ Git ได้จาก RelNotes หรือถ้าอยากอ่านแบบเข้าใจง่ายขึ้นก็ดูได้ที่ หมวด Git ในบล็อก GitHub
ในกรณีของ git-branchless ก็มีฟีเจอร์อย่าง in-memory merge ที่เขียนด้วย Rust
เนื้อหาเกี่ยวกับ Rust ก็หาเพิ่มเติมได้ใน mailing list นั้น
(ไม่ได้จะประเมินเองว่าฝั่งไหนถูก แต่คงมีคนทำแทนอยู่แล้ว)
แทบไม่มีใครอยากพัฒนา Git ด้วย C แต่มีนักพัฒนาที่สนใจการ rewrite เป็น Rust และกระตือรือร้นจะเข้าร่วม
Git มีความสุกงอมสูงและน่าจะมีโค้ดใหม่เพิ่มไม่มาก
Rust ซับซ้อนกว่า C มาก
ถ้าจำเป็นต้องมีความสามารถเชิงวัตถุจริง ๆ ใช้แค่ C++98 ก็น่าจะง่ายและเข้าใจได้กว่ามากเมื่อเทียบกับ C++ สมัยใหม่หรือ Rust
ไม่ใช่ว่า Rust จะกลายเป็นข้อบังคับสำหรับแพตช์ในอนาคต แต่จะกลายเป็นข้อบังคับภายในระบบ build
ถ้ายังไม่ถูกก็แก้ได้อีก
หมายถึงต้องใช้เพื่อ build ตัวระบบ build เอง หรือจำเป็นต่อการ build แอปพลิเคชันด้วย
ตัวเองลงทุนกับ Git ไว้มากและสร้างหลายโปรเจกต์ จึงไม่อยากเสียความสามารถในการ hack Git ไป
ในความเป็นจริง Rust เรียนรู้ง่ายกว่า C ทั่วไป (โดยเฉพาะ C ที่มีบั๊กเยอะ) และง่ายกว่าการทำความเข้าใจซอร์สของ Git หรือ Linux อย่างแน่นอน
ตาม GitHub มีสัดส่วนเป็น C 50%, Shell 38%, Perl 4% ที่เหลือเป็น TCL/Python เป็นต้น
Perl/TCL ต่างหากที่ค่อนข้างเป็นข้อยกเว้น
โปรเจกต์เติบโตมาพร้อมโค้ด hack เฉพาะกิจจำนวนมากที่ถูกแปะเพิ่มไปเรื่อย ๆ และตอนนี้ก็น่าจะถึงเวลาปรับปรุงความปลอดภัย/ประสิทธิภาพ พร้อมเก็บกวาดโค้ดเก่าเหล่านั้น
จึงมองว่า Rust เหมาะกับงานนี้
และการที่ Git ใช้ Rust บางส่วนก็คงไม่ได้ขัดขวางการพัฒนา Git client หรือเซิร์ฟเวอร์ที่ตนสร้างเอง
ใน release notes ของ Debian ก็ระบุ ปัญหาที่เกี่ยวกับแพ็กเกจ Rust/Go ไว้ชัดเจน
เวลา build แพ็กเกจ Rust มักต้อง rebuild บ่อยเพราะปัญหา static link ทำให้ใช้งานจริงไม่สะดวก
ถ้าฝั่ง Rust ยังเมินปัญหาเรื่อง ABI ที่เสถียร/ไลบรารีแบบแชร์ซึ่งจำเป็นมากใน Linux OS ก็อาจสร้างความไม่พอใจได้มากกว่า C เสียอีก
จึงมองว่าสถาปัตยกรรมซอฟต์แวร์ขนาดใหญ่ควรระมัดระวังให้มากกว่านี้
ลองค้นหาคำว่า NonStop ในบทความนี้จะเห็นตัวอย่าง
ใน RESF และที่อื่น ๆ มักพูดว่า “แพลตฟอร์มไม่รองรับ Rust” แต่ความจริงคือต้องให้คอมไพเลอร์ Rust รองรับก่อนจึงจะใช้งานได้จริง
git ดูเหมือนจะนิ่งและเสถียรในสาย 2.x แล้ว จึงไม่เห็นเหตุผลที่จะต้องทำ breaking compatibility
จึงสงสัยว่าวัฒนธรรมการพัฒนายุคหลังเริ่มห่างไกลจากการใช้ toolchain แบบนี้หรือไม่
ทั้ง source control, การ build, และสภาพแวดล้อมรันงานมักต่างกัน ต้องอาศัยการคัดลอกไปยังรีโมตหรือการรันจากระยะไกล และกฎการ build ก็จำเป็นต้องตรวจจับแพลตฟอร์มเป้าหมายด้วย
ใช้เพียงแฟล็ก
--targetก็ build ได้ราว 100 แพลตฟอร์มโดยแทบไม่มีปัญหาปัญหาจริงน่าจะมาจากที่ทีมพัฒนา Git บางคนยังยึดติดกับข้อจำกัดของเครื่องพัฒนาเก่า ๆ หรือเครื่องที่ล็อกสเปกไว้
cross-compilation มักถูกมองเป็นพลเมืองชั้นสอง และในโปรเจกต์ภายนอกก็แทบไม่คาดหวังว่าจะใช้งานได้ดี
แม้แต่ Linux distribution บางตัวก็ให้ build สำหรับ Raspberry Pi บนฮาร์ดแวร์จริงเท่านั้น
ด้วยเหตุนี้จึงแทบไม่มีใครพยายามสนับสนุนมันอย่างจริงจัง
โดยเฉพาะบน Linux ที่แย่เป็นพิเศษ เพราะโครงสร้างของ glibc ล้าสมัยจนยากจะตั้งเป้าไปที่ glibc ขั้นต่ำบนฮาร์ดแวร์ใด ๆ
โปรเจกต์ส่วนใหญ่แทบไม่พยายามรองรับ cross-compilation เลย
Zig กำลังพยายามแก้ปัญหานี้อยู่
Git เป็นเครื่องมือแกนกลางของโปรเจกต์ต่าง ๆ ดังนั้นความเปลี่ยนแปลงจึงมีความเสี่ยงสูง และการทำให้เป็น dependency ที่จำเป็นภายในเวลาเพียง 6 เดือนนั้นอันตรายเกินไป
ความซับซ้อนนี้มีเป้าหมายเพื่อจับข้อผิดพลาดให้ได้มากขึ้นตอน compile time แต่ผลลัพธ์ก็คือภาษานั้นเองซับซ้อนมาก
ด้วยเหตุนี้จึงไม่แนะนำให้นำมาใช้
และเข้าใจว่าเคอร์เนลก็ปฏิเสธการนำ Rust มาใช้เช่นกัน
การเพิ่ม type system ระดับ Haskell และ macro system ระดับ Lisp เข้าไปในเคอร์เนลที่ซับซ้อนอยู่แล้ว ยิ่งเพิ่มความซับซ้อนขึ้น
การไล่ตามโค้ด Rust ผ่าน serde ก็ทำได้ยาก
ตรงกันข้าม Go มี Unmarshal ที่ตามรอยได้ง่ายกว่ามาก
เพราะสามารถใส่ข้อมูลให้คอมไพเลอร์เข้าใจได้มากกว่า
ไม่เคยมีปัญหาใหญ่กับ Serde และกลับต้องดีบัก Go Unmarshal บ่อยกว่า
ส่วนคำกล่าวอ้างว่าเคอร์เนลปฏิเสธ Rust นั้น ความจริงคือเป็นความขัดแย้งระหว่างนักพัฒนาสองคนเรื่องตำแหน่งเก็บ header
Rust อาจเริ่มต้นยากกว่า C แต่ช่องว่างระหว่าง “Rust ขั้นพื้นฐาน” กับ “Rust ที่เร็วและปลอดภัย” นั้นเล็กกว่าของ C มาก
และถูกมองว่าสำคัญพอ ๆ กับ borrow checker
Result/การจัดการ error มาก่อน ก็จะเรียน Rust ได้ค่อนข้างง่ายตัวภาษาก็ยืดหยุ่นพอสมควร
และ Linux kernel ก็ไม่ได้ปฏิเสธ Rust จริง ๆ