Raku ดำเนินการตรวจสอบประเภทใดในเวลารวบรวม อาจจะมีการเปลี่ยนแปลงในอนาคต?
ปัจจุบัน (ณ เดือนสิงหาคม 2020) Rakudo ไม่พิมพ์ตรวจสอบค่าส่งคืนของฟังก์ชันในเวลาคอมไพล์ นั่นคือไม่มีการรับประกันแบบคงที่ว่าฟังก์ชันตอบสนองข้อ จำกัด ในการส่งคืน โดยรวมแล้วทั้งสองฟังก์ชันต่อไปนี้จะรวบรวมเป็น Raku:
sub get-int(--> Int) { 'bug' }
sub get-int($a --> Int} { when $a == 5 { 'Rare bug' }
default { 42 }
}
ฉันมีคำถามที่เกี่ยวข้องสองข้อ:
มีวิธีใดบ้างที่จะทราบว่าขณะนี้การตรวจสอบการพิมพ์ (ถ้ามี) เกิดขึ้นในเวลาคอมไพล์ (ไม่ว่าจะผ่านทางรายชื่อที่มีคนเขียนบางแห่งในเอกสารหรือสถานที่กลางในแหล่งข้อมูล Rakudo) หรือมันเป็นการเฉพาะกิจมากกว่านั้น?
การขาดเวลาในการรวบรวมนี้เป็นการตรวจสอบการตัดสินใจออกแบบโดยเจตนาหรือไม่? หรือกำลังเพิ่มการพิมพ์แบบคงที่มากขึ้นการตรวจสอบสิ่งที่ดีที่จะมีวันหนึ่ง แต่ยังไม่ได้นำไปใช้?
(ฉันคุ้นเคยกับคำตอบที่ยอดเยี่ยมของ Johnathan เกี่ยวกับบทลงโทษด้านประสิทธิภาพสำหรับประเภท / ข้อ จำกัด ใน Raku?ซึ่งระบุว่า "Raku บังคับใช้ข้อ จำกัด ประเภทที่เขียนลงในโปรแกรมเมื่อรันไทม์ล่าสุด " คำตอบนั้นอธิบายถึงวิธีต่างๆในการหลีกเลี่ยงการรัน - ค่าใช้จ่ายตามเวลาของการตรวจสอบการพิมพ์ แต่ไม่ได้อธิบายถึงสิ่งที่ต้องทำในเวลารวบรวม (ซึ่งแน่นอนว่าจะหลีกเลี่ยงค่ารันไทม์!)
คำตอบ
ขณะนี้การตรวจสอบประเภททำได้น้อยมากในเวลาคอมไพล์ ซึ่งส่วนใหญ่เกิดขึ้นเป็นผลข้างเคียงของเครื่องมือเพิ่มประสิทธิภาพแบบคงที่ การตรวจสอบวันนี้ส่วนใหญ่เกี่ยวกับการเรียกรูทีนย่อยโดยที่:
- เราสามารถกำหนดความเที่ยงตรงของการโทรและรู้ว่าจำนวนอาร์กิวเมนต์ที่ส่งผ่านจะไม่ตรงกัน
- เรามีข้อโต้แย้งตามตัวอักษรและเห็นได้ว่าพวกเขาไม่เคยตรงกับลายเซ็น
นี่เป็นส่วนที่เหลือจากเมื่อเครื่องมือเพิ่มประสิทธิภาพแบบคงที่ทำงานในการฝังตัวมากขึ้น ทุกวันนี้มันจะแทรกตัวดำเนินการเนทีฟในเวลาคอมไพล์เท่านั้นและปล่อยส่วนที่เหลือไว้สำหรับเครื่องมือเพิ่มประสิทธิภาพแบบไดนามิกของ VM ซึ่งมีความสามารถมากกว่าในการอินไลน์และยังสามารถ Uninline ได้ (อนุญาตให้มีการเพิ่มประสิทธิภาพการเก็งกำไร แต่ยังหมายถึงการติดตามสแต็กดั้งเดิมสามารถกู้คืนได้ เครื่องมือเพิ่มประสิทธิภาพแบบคงที่สูญเสียข้อมูลนี้)
การทำมากขึ้นในเวลารวบรวมถือว่าเป็นสิ่งที่พึงปรารถนาอย่างไรก็ตามมีประเด็นที่ควรพิจารณาในทางปฏิบัติ
- การแนะนำการตรวจสอบเพิ่มเติมอาจทำให้เกิดการแตกของโค้ดที่ใช้งานได้ พิจารณาโมดูลที่มีเส้นทางรหัสที่จะล้มเหลวในการตรวจสอบเวลาคอมไพล์ที่เข้มงวดขึ้น แต่กำลังถูกใช้ในระบบที่ไม่เคยทำงานในกรณีนั้น หากคอมไพเลอร์เริ่มต้นล้มเหลวในการคอมไพเลอร์เวอร์ชันใหม่กว่าก็จะไม่สามารถปรับใช้ระบบนั้นได้หลังจากอัพเกรดคอมไพเลอร์ โดยทั่วไปหมายความว่าการตรวจสอบที่ดำเนินการควรเปลี่ยนเมื่อมีการเปลี่ยนแปลงเวอร์ชันภาษา (ซึ่งหมายความว่าผู้คนควรประกาศเวอร์ชันภาษาที่พวกเขากำลังเขียนเมื่อเขียนโค้ดด้วยใจ)
- การตรวจสอบที่ดำเนินการมากขึ้นในเวลาคอมไพล์จะ "หลีกเลี่ยงต้นทุนรันไทม์อย่างแน่นอน" อาจเป็นจริง แต่ก็ไม่สำคัญสำหรับเหตุผล รันไทม์ที่มีการจัดการไม่สามารถเชื่อถือคำสัญญาที่ทำไว้ในรหัส bytecode ที่ให้ไว้แบบสุ่มสี่สุ่มห้าเนื่องจากอาจนำไปสู่การละเมิดความปลอดภัยของหน่วยความจำ (ซึ่งนำไปสู่ SIGSEGV หรือแย่กว่านั้น) นี่เป็นความจริงอย่างชัดเจนในภาษาเช่น Raku ซึ่งความหมายของการตรวจสอบประเภทสามารถตั้งโปรแกรมได้ แต่เป็นจริงใน JVM, CLR และอื่น ๆ การชนะที่เกี่ยวข้องกับประเภทที่ใหญ่ที่สุดใน Raku มาจากการใช้งานประเภทดั้งเดิมซึ่งสามารถหลีกเลี่ยงการจัดสรรจำนวนมากและทำให้งานเก็บขยะ
- การดำเนินการตรวจสอบเพิ่มเติมจะเพิ่มความซับซ้อนของคอมไพเลอร์และระยะเวลาที่ต้องใช้ในการรวบรวม ประการแรกเป็นปัญหาอยู่แล้ว ส่วนหน้าของคอมไพเลอร์ไม่เห็นการเปลี่ยนแปลงทางสถาปัตยกรรมที่สำคัญในรอบทศวรรษ งาน RakuAST ในปัจจุบันที่วางรากฐานสำหรับมาโครยังเกี่ยวข้องกับการเขียนซ้ำส่วนหน้าของคอมไพเลอร์ สถาปัตยกรรมที่ได้รับการปรับปรุงควรช่วยให้สามารถใช้การตรวจสอบประเภทเวลาคอมไพล์เพิ่มเติมได้ง่ายขึ้น แต่ยังคิดว่าแง่มุมของการคอมไพล์อาจจะขนานกันได้อย่างไรซึ่งจะทำให้คอมไพเลอร์ทำงานได้มากขึ้นโดยไม่ต้องเพิ่มเวลาคอมไพล์วอลล์
เมื่อการยกเครื่องส่วนหน้าของคอมไพเลอร์ปัจจุบันเสร็จสมบูรณ์แล้วการตรวจสอบเวลาคอมไพล์เพิ่มเติมจะถูกนำมาใช้ (แต่เปิดใช้งานจากเวอร์ชันภาษาถัดไปเท่านั้น) ดูเหมือนจะค่อนข้างเป็นไปได้ - อย่างน้อยก็ตราบใดที่ยังมีคนทำงานอยู่
อย่างไรก็ตามมีโอกาสที่น่าตื่นเต้นยิ่งขึ้นในพื้นที่นี้เนื่องจากจะมี API สำหรับโปรแกรม Raku และด้วยแผนการที่มาพร้อมกันสำหรับการส่งผ่านคอมไพเลอร์ที่กำหนดเองจึงเป็นไปได้ที่จะใช้ตัวตรวจสอบประเภทเป็นโมดูลในไม่ช้า! บางส่วนอาจนำไปสู่การตรวจสอบที่ทำให้เป็นเวอร์ชันภาษา Raku ในอนาคต คนอื่น ๆ อาจค่อนข้างเฉพาะโดเมนและมุ่งเป้าไปที่การเปิดใช้งานโมดูลที่กำหนดให้ถูกต้องมากขึ้น คนอื่น ๆ อาจบังคับใช้ความเข้มงวดที่ไม่ได้เป็นไปตามเจตนารมณ์ของภาษาพื้นฐาน แต่ผู้ใช้บางภาษาอาจต้องการเลือกใช้