การทบทวนหนังสือที่มีอิทธิพลของ Andrew Appel เรื่อง Compiling with Continuations ที่ตีพิมพ์ในปี 1992 เมื่อเร็วๆ นี้ ได้จุดประกายการอภิปรายอย่างเร่าร้อนในชุมชนภาษาโปรแกรมมิ่งเกี่ยวกับวิวัฒนาการของการแทนค่าระดับกลางของคอมไพเลอร์ และว่า continuation-passing style (CPS) ยังคงมีความเกี่ยวข้องในการออกแบบคอมไพเลอร์สมัยใหม่หรือไม่
หนังสือเล่มนี้ซึ่งอธิบายรายละเอียดเกี่ยวกับวิธีการสร้างคอมไพเลอร์โดยใช้ continuations เป็นการแทนค่าระดับกลาง ถือเป็นงานที่ก้าวล้ำสำหรับยุคสมัยนั้น หนังสือแสดงให้เห็นว่าโปรแกรม Standard ML สามารถถูกแปลงผ่านหลายขั้นตอน - จาก MiniML ไปยัง Lambda ไปยัง CPS - ก่อนที่จะถูกคอมไพล์เป็นรหัสเครื่อง แนวทางนี้สัญญาว่าจะให้วิธีแก้ปัญหาที่สง่างามสำหรับปัญหาคอมไพเลอร์ที่ซับซ้อน เช่น closure conversion และ register allocation
โครงสร้างหนังสือและภาษาโปรแกรม
- หนังสือต้นฉบับ: "Compiling with Continuations" โดย Andrew Appel (1992)
- ไปป์ไลน์การคอมไพล์: MiniML → Lambda → CPS → Abstract Machine Code
- ภาษาเป้าหมาย: Standard ML (SML)
- บทสำคัญ:
- บทที่ 2-3: ภาษา CPS และความหมายเชิงความหมาย
- บทที่ 4: การใช้งาน MiniML
- บทที่ 5: การคอมไพล์จาก Lambda ไปยัง CPS
- บทที่ 10-11: การแปลง Closure และ register spilling
ความแตกแยกครั้งใหญ่ของ IR: CPS กับ SSA
การถกเถียงที่เร่าร้อนที่สุดมุ่งเน้นไปที่ว่า CPS ถูกแทนที่ด้วย Static Single Assignment (SSA) form หรือไม่ ซึ่งได้กลายเป็นการแทนค่าระดับกลางที่โดดเด่นในคอมไพเลอร์สมัยใหม่ สมาชิกในชุมชนแบ่งออกเป็นสองฝ่ายในคำถามพื้นฐานนี้ บางคนโต้แย้งว่า CPS ตายแล้วในฐานะ IR และ SSA ชนะ โดยชี้ไปที่วิธีที่แม้แต่คอมไพเลอร์ SML/NJ ก็ละทิ้ง CPS ในที่สุดเพื่อใช้ MLRISC และต่อมาใช้ LLVM
อย่างไรก็ตาม คนอื่นๆ ปกป้องความเกี่ยวข้องที่ยังคงมีอยู่ของ CPS โดยเฉพาะสำหรับภาษาฟังก์ชันนัลและกรณีการใช้งานเฉพาะ นักพัฒนาเกมพบว่าการแปลง CPS มีประโยชน์อย่างยิ่งสำหรับการใช้งานโครงสร้างการเขียนโปรแกรมแบบอะซิงโครนัสโดยไม่ต้องมีความซับซ้อนของการสนับสนุน call/cc (call-with-current-continuation) แบบเต็มรูปแบบ
หมายเหตุ: CPS (Continuation-Passing Style) เป็นรูปแบบการเขียนโปรแกรมที่ฟังก์ชันไม่เคยส่งคืนค่าโดยตรง แต่จะส่งผลลัพธ์ไปยังฟังก์ชัน continuation แทน SSA (Static Single Assignment) เป็นการแทนค่าระดับกลางที่ตัวแปรแต่ละตัวถูกกำหนดค่าเพียงครั้งเดียว
วิวัฒนาการของคอมไพเลอร์สมัยใหม่
- เส้นทางของคอมไพเลอร์ SML/NJ: CPS → MLRISC → LLVM
- แนวทางทางเลือก:
- SSA (Static Single Assignment) - IR หลักของยุคปัจจุบัน
- ANF (Administrative Normal Form) - แนวทางแบบผสมผสาน
- IR ที่ใช้ sequent calculus - งานวิจัยล้ำสมัย
- ข้อพิจารณาด้านประสิทธิภาพ: การทำนาย branch มีความเหมาะสมกับ call/return มากกว่า indirect jumps
ผลกระทบทางวิชาการกับการใช้งานจริง
การอภิปรายเผยให้เห็นความตึงเครียดที่น่าสนใจระหว่างอิทธิพลทางวิชาการและการนำไปใช้จริง ในขณะที่หนังสือเล่มนี้ก่อให้เกิดเอกสารติดตามจำนวนมากที่มีจำนวนการอ้างอิงที่น่าประทับใจ - รวมถึง The Essence of Compiling with Continuations ที่ถูกอ้างอิง 806 ครั้ง - นักพัฒนาต่างดิ้นรนที่จะหาการใช้งานที่ทำงานได้หรือการประยุกต์ใช้เทคนิคเหล่านี้ในยุคสมัยใหม่
ความขาดการเชื่อมต่อนี้เน้นย้ำถึงปัญหาที่กว้างขึ้นในวรรณกรรมวิทยาการคอมพิวเตอร์: งานวิชาการที่ถูกอ้างอิงสูงไม่ได้แปลว่าจะมีการใช้งานจริงอย่างแพร่หลายเสมอไป การขาดแคลน repositories ใน GitHub บล็อกโพสต์ หรือการใช้งานสมัยใหม่ บ่งบอกว่าแม้ไอเดียเหล่านี้จะมีอิทธิพลทางปัญญา แต่อาจไม่ได้หาทางเข้าสู่การสร้างคอมไพเลอร์ในชีวิตประจำวัน
งานวิจัยติดตาม
- "The Essence of Compiling with Continuations" (1993) - ถูกอ้างอิง 806 ครั้ง
- "Compiling with Continuations, Continued" (2007) - ถูกอ้างอิง 154 ครั้ง
- "Compiling with continuations, or without? whatever." (2019) - ถูกอ้างอิง 34 ครั้ง
ทางเลือกสมัยใหม่และวิวัฒนาการ
ชุมชนคอมไพเลอร์ส่วนใหญ่ได้เปลี่ยนไปใช้แนวทางที่แตกต่างกัน Administrative Normal Form (ANF) ได้รับความนิยมในฐานะทางกลาง โดยเสนอประโยชน์บางอย่างของ CPS โดยไม่มีความซับซ้อน ในขณะเดียวกัน การวิจัยที่ล้ำสมัยสำรวจการแทนค่าระดับกลางที่อิงตาม sequent calculus ซึ่งสามารถแสดง continuations ได้อย่างเป็นธรรมชาติมากกว่า CPS แบบดั้งเดิม
ข้อกังวลเรื่อง branch prediction ยังสนับสนุนรูปแบบคำสั่ง call/return แบบดั้งเดิมมากกว่า indirect jumps ที่การคอมไพล์ CPS มักจะสร้างขึ้น ทำให้ CPS มีความน่าสนใจน้อยลงสำหรับแอปพลิเคชันที่ต้องการประสิทธิภาพสูงบนโปรเซสเซอร์สมัยใหม่
คำตัดสินเกี่ยวกับความเกี่ยวข้อง
แม้จะมีการวิพากษ์วิจารณ์ นักพัฒนาหลายคนที่ได้ศึกษาหนังสือเล่มนี้พบคุณค่าที่แท้จริงในการทำความเข้าใจแนวคิดของมัน เทคนิคสำหรับ closure conversion, register spilling และการเพิ่มประสิทธิภาพยังคงมีคุณค่าทางการศึกษา แม้ว่าแนวทาง CPS เฉพาะจะไม่เป็นที่นิยมแล้วก็ตาม
การถกเถียงในที่สุดสะท้อนถึงวิวัฒนาการอย่างรวดเร็วของเทคโนโลยีคอมไพเลอร์ในช่วงสามทศวรรษที่ผ่านมา สิ่งที่ดูเหมือนจะปฏิวัติในปี 1992 อาจดูล้าสมัยในวันนี้ แต่ข้อมูลเชิงลึกพื้นฐานเกี่ยวกับการแปลงโปรแกรมและการแทนค่าระดับกลางยังคงมีอิทธิพลต่อการออกแบบคอมไพเลอร์สมัยใหม่ แม้ว่าจะแสดงออกผ่านแนวทางทางเทคนิคที่แตกต่างกัน
อ้างอิง: Compiling with Continuations