หนังสือ "Compiling with Continuations" ของ Appel จุดประกายการถ่ายเถียงเรื่อง CPS กับ SSA ในการออกแบบคอมไพเลอร์สมัยใหม่

ทีมชุมชน BigGo
หนังสือ "Compiling with Continuations" ของ Appel จุดประกายการถ่ายเถียงเรื่อง CPS กับ SSA ในการออกแบบคอมไพเลอร์สมัยใหม่

การทบทวนหนังสือที่มีอิทธิพลของ 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