ดีไซน์ Async I/O ใหม่ของ Zig ก่อให้เกิดการถกเถียงเกี่ยวกับปรัชญาภาษาและการนำไปปฏิบัติ

ทีมชุมชน BigGo
ดีไซน์ Async I/O ใหม่ของ Zig ก่อให้เกิดการถกเถียงเกี่ยวกับปรัชญาภาษาและการนำไปปฏิบัติ

การเปิดตัวเวอร์ชัน 0.12.0 ที่จะมาถึงของ Zig กำลังนำเสนอแนวทางใหม่ในการจัดการ asynchronous I/O ที่สร้างการอภิปรายอย่างมีนัยสำคัญในชุมชนโปรแกรมเมอร์ ซึ่งแตกต่างจากการนำเสนอ async/await แบบดั้งเดิมในภาษาอื่น ดีไซน์ของ Zig ปฏิบัติต่อการดำเนินการแบบ async อย่างเป็นอินเทอร์เฟซที่สามารถปรับเปลี่ยนได้ (pluggable interfaces) แทนที่จะเป็นโครงสร้างในระดับภาษา สร้างทั้งความตื่นเต้นและความกังวลในหมู่ผู้พัฒนาซอฟต์แวร์เกี่ยวกับทิศทางและปรัชญาของภาษา

แนวทางที่แตกต่างสำหรับการเขียนโปรแกรมแบบอะซิงโครนัส

นวัตกรรมหลักในระบบ async I/O ใหม่ของ Zig อยู่ที่การแยกความกังวลระหว่างการแสดงออกถึงความเป็นอะซิงโครนัสและการนำมันไปปฏิบัติ แทนที่จะระบุฟังก์ชันด้วยคีย์เวิร์ด async ที่เปลี่ยนพวกมันเป็น state machines, Zig ได้แนะนำพารามิเตอร์อินเทอร์เฟซ io ที่สามารถส่งผ่านไปยังฟังก์ชันต่างๆ ได้ ซึ่งทำให้การนำ I/O ไปปฏิบัติที่แตกต่างกัน - ตั้งแต่แนวทางแบบเธรดธรรมดาไปจนถึงระบบคอรูทีนที่ซับซ้อน - สามารถทำงานกับโค้ดแอปพลิเคชันเดียวกันได้ ดีไซน์นี้ให้ความสำคัญกับความปลอดภัยในการยกเลิกและการจัดการทรัพยากรผ่านทาง primitives อย่าง nocancel ที่จัดการการทำความสะอาดโดยอัตโนมัติเมื่อการดำเนินการล้มเหลวหรือถูกยกเลิก

ผู้แสดงความคิดเห็นหนึ่งคนได้ชี้ให้เห็นถึงความแตกต่างพื้นฐานจากภาษาอื่นๆ: ใน Zig, คอมไพเลอร์เคยสนับสนุนคอรูทีน แต่สิ่งนี้ถูกเอาออกไปแล้ว ในดีไซน์ใหม่, async และ await เป็นแค่ฟังก์ชันเท่านั้น ในการนำไปปฏิบัติแบบเธรดที่ใช้ในการสาธิต, await แค่บล็อกเธรดจนกว่าการดำเนินการจะเสร็จสิ้น

Zig Async I/O Primitives หลัก:

  • io.async: สร้างฟังก์ชันให้ทำงานในพื้นหลัง จะทำงานทันทีหากไม่มีการทำงานพร้อมกันอื่น
  • await: บล็อกจนกว่าการทำงานแบบ async จะเสร็จสมบูรณ์
  • nocancel: คล้ายกับ await แต่จะส่งคำขอยกเลิกด้วย
  • ทั้ง await และ nocancel มีคุณสมบัติ idempotent เมื่อใช้ร่วมกัน

ความกังวลของชุมชนเกี่ยวกับความซับซ้อนและการออกแบบ

ชุมชนโปรแกรมเมอร์ได้แสดงปฏิกิริยาที่หลากหลายต่อทิศทางใหม่นี้ นักพัฒนาบางส่วนกังวลว่า Zig กำลังเคลื่อนห่างจากปรัชญาดั้งเดิมของมันในฐานะภาษาระดับต่ำที่เรียบง่าย การนำเสนอสิ่งที่ดูเหมือนจะเป็นระบบเอฟเฟกต์ (effect system) สำหรับ I/O และการจัดสรรหน่วยความจำได้ทำให้เกิดคำถามว่าความซับซ้อนนี้สอดคล้องกับค่านิยมหลักของ Zig หรือไม่ ผู้วิจารณ์ชี้ให้เห็นว่าอินเทอร์เฟซ IO มีความคล้ายคลึงกับการเขียนโปรแกรมเชิงวัตถุแต่อาจละเมิดหลักการอย่างหลักการแทนที่ของลิสคอฟ (Liskov substitution principle) สร้างการโต้ตอบที่ไม่ได้คาดหมายเมื่อออบเจกต์ IO ถูกใช้ร่วมกันข้ามขอบเขตของไลบรารี

ฉันพบว่าทิศทางของ zig น่าสับสน มันควรจะเป็นภาษาที่เรียบง่ายหรือภาษาที่ซับซ้อน? ระดับต่ำหรือระดับสูง? ฟีเจอร์นี้สำหรับฉันคือส่วนผสมที่แปลกประหลาดระหว่างฟังก์ชันการทำงานระดับสูงและระดับต่ำและค่อนข้างซับซ้อน

การอภิปรายนี้เน้นย้ำถึงความตึงเครียดในการออกแบบภาษา: จะให้การสรุปความ (abstractions) ที่ทรงพลังในขณะที่ยังคงรักษาความเรียบง่ายและความสามารถในการคาดเดาได้อย่างไร นักพัฒนาบางส่วนชื่นชมที่ Zig กำลังทดลองกับทางเลือกอื่นแทน async/await แบบดั้งเดิม ในขณะที่คนอื่นๆ กังวลเกี่ยวกับเส้นทางการเรียนรู้และศักยภาพของการไหลของควบคุมที่ซ่อนอยู่

การกระจายความเห็นของชุมชน:

  • สนับสนุนนวัตกรรม: ~40%
  • กังวลเกี่ยวกับความซับซ้อน: ~35%
  • เป็นกลาง/สังเกตการณ์: ~25%
  • ความกังวลหลัก: ความสอดคล้องของ standard library, การควบคุมการทำงานที่ซ่อนอยู่, ความสอดคล้องทางปรัชญา

การอภิปรายเกี่ยวกับ Standard Library และวิวัฒนาการของภาษา

เหนือไปกว่าการอภิปรายเกี่ยวกับ async I/O ความคิดเห็นได้เผยให้เห็นการอภิปรายที่กำลังดำเนินอยู่เกี่ยวกับปรัชญาการออกแบบ standard library ของ Zig สมาชิกในชุมชนบางส่วนพบว่า standard library ไม่สอดคล้องกัน โดยอธิบายว่ามันเป็นเหมือนชุดของแพ็กเกจเล็กๆ ไม่ใช่หน่วยที่เชื่อมโยงกัน การขาดตัวปรับแต่งการมองเห็น (visibility modifiers) และการแยกที่ชัดเจนระหว่างอินเทอร์เฟซสาธารณะและรายละเอียดการนำไปปฏิบัติภายในได้สร้างความหงุดหงิดให้กับนักพัฒนาที่ต้องการการรับประกันการห่อหุ้ม (encapsulation) ที่แข็งแกร่งกว่า

ในเวลาเดียวกัน นักพัฒนาคนอื่นๆ ชื่นชมในความสามารถในการเข้าถึงรายละเอียดการนำไปปฏิบัติภายในเมื่อจำเป็น ผู้แสดงความคิดเห็นหนึ่งคนได้แบ่งปันว่า: โดยสุจริต การได้ยุ่งกับรายละเอียดการนำไปปฏิบัติภายในเป็นส่วนที่ฉันชอบที่สุดในการใช้ standard library ของ Zig สิ่งนี้สะท้อนถึงปรัชญาของ Zig ในการให้การควบคุมสูงสุดแก่โปรแกรมเมอร์ แม้ว่ามันจะหมายถึงการยอมรับความรับผิดชอบมากขึ้นสำหรับการใช้งานที่ถูกต้อง

อนาคตของเรื่องราว Concurrency ของ Zig

เมื่อมองไปข้างหน้า เรื่องราว async I/O ของ Zig ยังคงวิวัฒนาการอยู่ การนำไปปฏิบัติในปัจจุบันใช้เธรด แต่มีแผนสำหรับคอรูทีนแบบมีสแต็ก (stackful coroutines) โดยใช้ io_uring และ kqueue รวมถึงคอรูทีนแบบไม่มีสแต็ก (stackless coroutines) ที่อาจเกิดขึ้น อย่างไรก็ตาม ความท้าทายทางเทคนิคที่สำคัญยังคงอยู่ โดยเฉพาะอย่างยิ่งรอบๆ การคำนวณขนาดสแต็กแบบสถิต (static stack size) สำหรับคอรูทีนแบบมีสแต็ก ซึ่งสิ่งนี้จะต้องห้ามหรือติดตามการเรียกซ้ำ (recursion) และการเรียกฟังก์ชันแบบไดนามิกอย่างระมัดระวัง - ข้อจำกัดที่ไม่ใช่เรื่องเล็กน้อยสำหรับภาษาการเขียนโปรแกรมระบบ

ชุมชนดูเหมือนจะแบ่งออกในประเด็นว่าแผนการที่ทะเยอทะยานเหล่านี้จะบรรลุผลสำเร็จหรือไม่ บางคนเห็นศักยภาพสำหรับนวัตกรรมที่ล้ำสมัย ขณะที่คนอื่นๆ กังวลเกี่ยวกับ vaporware เมื่อพิจารณาถึงความซับซ้อนของปัญหาที่กำลังถูกแก้ไข การอภิปรายรอบๆ การกำจัด stack overflow ผ่านการวิเคราะห์แบบสถิต (static analysis) นั้นมีความทะเยอทะยานเป็นพิเศษและสามารถให้ประโยชน์อย่างมีนัยสำคัญสำหรับระบบสมองกลฝังตัว (embedded systems) หากนำไปปฏิบัติได้สำเร็จ

การใช้งาน I/O ที่วางแผนไว้:

  • Threaded (การใช้งานปัจจุบัน)
  • Stackful coroutines โดยใช้ io_uring/kqueue
  • Stackless coroutines (อยู่ในขั้นตอนการออกแบบ)
  • การใช้งานทั้งหมดทำงานร่วมกับโค้ดแอปพลิเคชันเดียวกันผ่านอินเทอร์เฟซ io

สรุป

ดีไซน์ async I/O ใหม่ของ Zig เป็นตัวแทนของการทดลองที่กล้าหาญในการออกแบบภาษาที่ท้าทายแนวทางดั้งเดิมในการจัดการ concurrency โดยการปฏิบัติต่อ async อย่างเป็นอินเทอร์เฟซที่ปรับเปลี่ยนได้ แทนที่จะเป็นคุณสมบัติของภาษา Zig ตั้งเป้าที่จะหลีกเลี่ยงปัญหาการระบายสีฟังก์ชัน (function coloring problem) ที่รบกวนภาษาอื่นๆ ในขณะที่ให้ความยืดหยุ่นในการนำไปปฏิบัติ อย่างไรก็ตาม แนวทางนี้มาพร้อมกับความซับซ้อนของมันเองและคำถามเชิงปรัชญาเกี่ยวกับว่าภาษา Zig ควรจะเป็นภาษาแบบไหน

ดังที่ผู้แสดงความคิดเห็นหนึ่งคนได้สรุปอย่างเหมาะสม, Zig ไม่ได้แค่เต็มไปด้วยความคิดที่ดีเท่านั้น แต่มันยังมีสุสานแห่งความคิดทั้งหลายที่ถูกโยนทิ้งไปด้วย ข้อเสนอ async I/O ในปัจจุบันยังคงสืบสานประเพณีการประเมินการออกแบบอย่างเข้มงวดนี้ ไม่ว่าความคิดนี้โดยเฉพาะจะเติบโตหรือเข้าร่วมสุสานนั้นยังคงต้องรอดู แต่การอภิปรายของชุมชนที่มีชีวิตชีวาเป็นการรับประกันว่าวิวัฒนาการของ Zig จะยังคงเป็นไปอย่างรอบคอบและไตร่ตรอง

อ้างอิง: Zig's New Async I/O (Text Version)