ประเภทการลบเป็นสิ่งที่ดี
มาติดตามข้อเท็จจริงกันเถอะ
คำตอบมากมายในตอนนี้เกี่ยวข้องกับผู้ใช้ Twitter มากเกินไป การให้ความสำคัญกับข้อความไม่ใช่ผู้ส่งสารจะเป็นประโยชน์ มีข้อความที่ค่อนข้างสอดคล้องกับข้อความที่ตัดตอนมาที่กล่าวถึงจนถึงตอนนี้:
เป็นเรื่องตลกเมื่อผู้ใช้ Java บ่นเกี่ยวกับการลบประเภทซึ่งเป็นสิ่งเดียวที่ Java มีสิทธิ์ในขณะที่เพิกเฉยต่อสิ่งที่ผิดพลาดทั้งหมด
ฉันได้รับผลประโยชน์มากมาย (เช่นค่าพาราเมตริก) และค่าใช้จ่าย (ค่าใช้จ่ายที่ถูกกล่าวหาคือขีด จำกัด ของจินตนาการ)
new T เป็นโปรแกรมที่เสีย มันเป็นไอโซมอร์ฟิกสำหรับคำกล่าวอ้าง "ข้อเสนอทั้งหมดเป็นจริง" ฉันไม่ใหญ่ในเรื่องนี้
เป้าหมาย: โปรแกรมที่เหมาะสม
ทวีตเหล่านี้สะท้อนให้เห็นถึงมุมมองที่ไม่สนใจว่าเราจะทำให้เครื่องทำอะไรได้บ้าง แต่เพิ่มเติมว่าเราสามารถให้เหตุผลว่าเครื่องจะทำบางสิ่งที่เราต้องการจริงหรือไม่ การใช้เหตุผลที่ดีเป็นเครื่องพิสูจน์ หลักฐานสามารถระบุได้ในสัญกรณ์ที่เป็นทางการหรือเป็นทางการ โดยไม่คำนึงถึงภาษาข้อกำหนดจะต้องชัดเจนและเข้มงวด ข้อกำหนดอย่างไม่เป็นทางการไม่สามารถจัดโครงสร้างได้อย่างถูกต้อง แต่มักจะมีข้อบกพร่องในการเขียนโปรแกรมเชิงปฏิบัติ เราจบลงด้วยการแก้ไขเช่นการทดสอบอัตโนมัติและการทดสอบเชิงสำรวจเพื่อชดเชยปัญหาที่เรามีโดยใช้เหตุผลอย่างไม่เป็นทางการ นี่ไม่ได้หมายความว่าการทดสอบเป็นความคิดที่ไม่ดีอย่างแท้จริง แต่ผู้ใช้ Twitter ที่อ้างถึงแนะนำว่ามีวิธีที่ดีกว่ามาก
ดังนั้นเป้าหมายของเราคือการมีโปรแกรมที่ถูกต้องซึ่งเราสามารถให้เหตุผลอย่างชัดเจนและเข้มงวดในลักษณะที่สอดคล้องกับวิธีที่เครื่องจะดำเนินการโปรแกรม แม้ว่านี่ไม่ใช่เป้าหมายเดียว เราต้องการให้ตรรกะของเรามีระดับการแสดงออกด้วย ตัวอย่างเช่นมีเพียงสิ่งเดียวเท่านั้นที่เราสามารถแสดงด้วยตรรกะเชิงประพจน์ เป็นเรื่องดีที่มีการหาปริมาณสากล (∀) และอัตถิภาวนิยม (∃) จากสิ่งต่างๆเช่นตรรกะลำดับที่หนึ่ง
การใช้ระบบประเภทเพื่อการให้เหตุผล
เป้าหมายเหล่านี้สามารถแก้ไขได้อย่างดีตามระบบประเภท นี้เป็นที่ชัดเจนโดยเฉพาะอย่างยิ่งเพราะแกงโฮเวิร์ดจดหมาย การโต้ตอบนี้มักจะแสดงด้วยการเปรียบเทียบดังต่อไปนี้ประเภทต่างๆเป็นไปตามโปรแกรมตามทฤษฎีบทมีไว้เพื่อพิสูจน์
การติดต่อนี้ค่อนข้างลึกซึ้ง เราสามารถใช้นิพจน์เชิงตรรกะและแปลผ่านการโต้ตอบกับประเภท ถ้าเรามีโปรแกรมที่มีลายเซ็นประเภทเดียวกับที่คอมไพล์เราได้พิสูจน์แล้วว่านิพจน์เชิงตรรกะนั้นเป็นจริงในระดับสากล (tautology) เนื่องจากการติดต่อเป็นสองทาง การเปลี่ยนแปลงระหว่างประเภท / โปรแกรมและโลกแห่งทฤษฎีบท / การพิสูจน์นั้นเป็นแบบกลไกและในหลาย ๆ กรณีอาจเป็นไปโดยอัตโนมัติ
Curry-Howard มีบทบาทอย่างดีในสิ่งที่เราต้องการทำกับข้อกำหนดสำหรับโปรแกรม
ระบบประเภทมีประโยชน์ใน Java หรือไม่?
แม้จะมีความเข้าใจใน Curry-Howard แต่บางคนก็พบว่ามันง่ายที่จะละทิ้งคุณค่าของระบบประเภทเมื่อเป็นเช่นนั้น
- เป็นเรื่องยากมากที่จะทำงานด้วย
- สอดคล้อง (ผ่าน Curry-Howard) กับตรรกะที่มีการแสดงออกที่ จำกัด
- เสีย (ซึ่งได้รับการกำหนดลักษณะของระบบว่า "อ่อนแอ" หรือ "แข็งแกร่ง")
เกี่ยวกับประเด็นแรกบางที IDE อาจทำให้ระบบประเภทของ Java ง่ายพอที่จะทำงานร่วมกับ (ซึ่งเป็นอัตนัยสูง)
เกี่ยวกับประเด็นที่สอง Java เกิดขึ้นเกือบจะสอดคล้องกับตรรกะลำดับที่หนึ่ง Generics ให้ใช้ระบบประเภทที่เทียบเท่ากับการหาปริมาณสากล น่าเสียดายที่ไวด์การ์ดให้การหาปริมาณอัตถิภาวนิยมเพียงเล็กน้อยเท่านั้น แต่การหาปริมาณแบบสากลเป็นการเริ่มต้นที่ดี เป็นเรื่องดีที่สามารถพูดได้ว่าฟังก์ชันสำหรับการList<A>
ทำงานในระดับสากลสำหรับรายการที่เป็นไปได้ทั้งหมดเนื่องจาก A ไม่มีข้อ จำกัด อย่างสมบูรณ์ สิ่งนี้นำไปสู่สิ่งที่ผู้ใช้ Twitter กำลังพูดถึงเกี่ยวกับ "พาราเมตริก"
บทความที่มักอ้างถึงเกี่ยวกับพาราเมตริกคือTheoremsของ Philip Wadler ฟรี! . สิ่งที่น่าสนใจเกี่ยวกับบทความนี้คือจากลายเซ็นประเภทเพียงอย่างเดียวเราสามารถพิสูจน์ค่าคงที่ที่น่าสนใจได้ ถ้าเราจะเขียนการทดสอบอัตโนมัติสำหรับค่าคงที่เหล่านี้เราจะเสียเวลาอย่างมาก ตัวอย่างเช่นList<A>
จากลายเซ็นชนิดเพียงอย่างเดียวสำหรับflatten
<A> List<A> flatten(List<List<A>> nestedLists);
เราสามารถให้เหตุผลว่า
flatten(nestedList.map(l -> l.map(any_function)))
≡ flatten(nestList).map(any_function)
นั่นเป็นตัวอย่างง่ายๆและคุณอาจให้เหตุผลเกี่ยวกับเรื่องนี้อย่างไม่เป็นทางการ แต่จะดีกว่าเมื่อเราได้รับการพิสูจน์อย่างเป็นทางการโดยไม่เสียค่าใช้จ่ายจากระบบ type และตรวจสอบโดยคอมไพเลอร์
การไม่ลบอาจนำไปสู่การละเมิดได้
จากมุมมองของการใช้งานภาษาทั่วไปของ Java (ซึ่งสอดคล้องกับประเภทสากล) มีบทบาทอย่างมากในพารามิเตอร์ที่ใช้ในการพิสูจน์ว่าโปรแกรมของเราทำอะไร สิ่งนี้นำไปสู่ปัญหาที่สามที่กล่าวถึง การได้รับการพิสูจน์และความถูกต้องทั้งหมดนี้จำเป็นต้องใช้ระบบประเภทเสียงที่ดำเนินการโดยไม่มีข้อบกพร่อง Java มีคุณสมบัติภาษาบางอย่างที่ช่วยให้เราสามารถทำลายเหตุผลของเราได้ ซึ่งรวมถึง แต่ไม่ จำกัด เพียง:
- ผลข้างเคียงกับระบบภายนอก
- การสะท้อนกลับ
ชื่อสามัญที่ไม่ถูกลบมีหลายวิธีที่เกี่ยวข้องกับการสะท้อน หากไม่มีการลบจะมีข้อมูลรันไทม์ที่มาพร้อมกับการใช้งานที่เราสามารถใช้เพื่อออกแบบอัลกอริทึมของเราได้ สิ่งนี้หมายความว่าคงที่เมื่อเราให้เหตุผลเกี่ยวกับโปรแกรมเราจะไม่มีภาพเต็ม การสะท้อนกลับคุกคามความถูกต้องของการพิสูจน์ใด ๆ ที่เราให้เหตุผลอย่างคงที่ การสะท้อนความบังเอิญไม่ได้นำไปสู่ข้อบกพร่องที่ยุ่งยากหลายประการ
แล้วยาชื่อสามัญที่ไม่ถูกลบมีวิธีใดบ้างที่ "มีประโยชน์" ลองพิจารณาการใช้งานที่กล่าวถึงในทวีต:
<T> T broken { return new T(); }
จะเกิดอะไรขึ้นถ้า T ไม่มีตัวสร้าง no-arg? ในบางภาษาสิ่งที่คุณได้รับเป็นค่าว่าง หรือบางทีคุณอาจข้ามค่า null และไปที่การเพิ่มข้อยกเว้น (ซึ่งค่า null ดูเหมือนจะนำไปสู่อยู่ดี) เนื่องจากภาษาของเราเป็นภาษาทัวริงสมบูรณ์จึงเป็นไปไม่ได้ที่จะให้เหตุผลว่าคำเรียกbroken
ใดจะเกี่ยวข้องกับประเภทที่ "ปลอดภัย" โดยไม่มีตัวสร้างที่ไม่มีข้อโต้แย้งและประเภทใดจะไม่ใช้ เราสูญเสียความมั่นใจว่าโปรแกรมของเราทำงานได้ในระดับสากล
การลบหมายความว่าเราได้ให้เหตุผลแล้ว (มาลบกันเถอะ)
ดังนั้นหากเราต้องการให้เหตุผลเกี่ยวกับโปรแกรมของเราเราไม่ควรใช้คุณลักษณะทางภาษาที่คุกคามการใช้เหตุผลของเราอย่างมาก เมื่อเราทำเช่นนั้นแล้วทำไมไม่เพียงแค่วางประเภทในรันไทม์? ไม่จำเป็น เราจะได้รับประสิทธิภาพและความเรียบง่ายบางอย่างด้วยความพึงพอใจที่ไม่มีการร่ายใด ๆ ล้มเหลวหรือวิธีการนั้นอาจขาดหายไปเมื่อทำการร้องขอ
การลบกระตุ้นการใช้เหตุผล