อะไรคือตัวอย่างที่ไม่ได้วางแผนไว้สำหรับการตรวจสอบประเภทคงที่ที่อนุรักษ์เกินไป?


9

ในแนวคิดในการเขียนโปรแกรมภาษาจอห์นมิทเชลเขียนว่าการตรวจสอบชนิดสแตติกจำเป็นต้องระมัดระวัง (เข้มงวดมากเกินไป) เนื่องจากปัญหาการหยุดทำงาน เขาให้เป็นตัวอย่าง:

if (complicated-expression-that-could-run-forever)
   then (expression-with-type-error)
   else (expression-with-type-error)

ใครสามารถให้คำตอบที่ไม่ได้วางแผนไว้ซึ่งจะเป็นข้อกังวลในทางปฏิบัติได้จริงหรือไม่?

ฉันเข้าใจว่า Java อนุญาตการปลดเปลื้องที่ตรวจสอบแบบไดนามิกสำหรับกรณีเช่นนี้:

if (foo instanceof Person) {
    Person p = (Person) foo;
    :
}

แต่ฉันพิจารณาถึงความจำเป็นของการขาดภาษา / คอมไพเลอร์ Java มากกว่าปัญหาข้ามภาษา


2
ตัวอย่าง Java ที่คุณให้ไว้เป็นตัวอย่างที่ไม่ได้วางแผนไว้สำหรับการตรวจสอบประเภทคงที่ซึ่งเข้มงวดเกินไป ใส่อีกวิธี: คำตอบนั้นขึ้นอยู่กับประเภทของระบบที่คุณมีอยู่ในใจ สำหรับตัวอย่างใด ๆ ที่เราเกิดขึ้นจะมีระบบพิมพ์ที่สามารถจัดการกับตัวอย่างนั้นได้เสมอ (ระบบพิมพ์ไม่ได้ระมัดระวังเกินไปในตัวอย่างนั้น) สำหรับระบบประเภทใด ๆ เราสามารถหาตัวอย่างที่มันอนุรักษ์เกินไป ดังนั้นฉันคิดว่าคุณต้องระบุระบบประเภท หากระบบประเภท Java ไม่ใช่สิ่งที่คุณมีอยู่ในใจมีอะไรพิเศษมากกว่าที่คุณคิดหรือไม่? การอนุมานประเภท ML
DW

หนึ่งอาจยืนยันว่าตัวอย่างคือหนึ่งในการวิเคราะห์รหัสคงที่เป็น "อนุรักษ์นิยม" ไม่ใช่การตรวจสอบประเภท nec มันจะเป็นประโยชน์ในการกำหนด"อนุรักษ์นิยม" เนื้อหาทุกประเภทระบบคงที่จะ"อนุรักษ์นิยม"เมื่อเทียบกับระบบแบบไดนามิกเพราะอดีตจะเข้มงวดมากขึ้นในเวลารวบรวมโดยคำจำกัดความ อย่างไรก็ตามหนึ่งอาจเถียงไม่เข้มงวดมากขึ้นที่รันไทม์เนื่องจากการตรวจสอบแบบไดนามิกสามารถกลับข้อผิดพลาดที่คล้ายกัน และโดยวิธีการตรวจสอบแบบไดนามิกรันไทม์ในภาษาที่ไม่ได้ขาดพวกเขาอยู่ในภาษาที่ตรวจสอบแบบคงที่ส่วนใหญ่อาจพิสูจน์ได้ว่ามิได้
vzn

คำตอบ:


7

ฉันมักจะมองว่ามันเป็นเรื่องของความสะดวกสบายมากกว่าที่เกี่ยวกับว่าอัลกอริทึมสามารถหรือไม่สามารถแสดงได้ทั้งหมด ถ้าฉันต้องการเรียกใช้โปรแกรมเช่นโปรแกรมที่ประดิษฐ์โดยมิทเชลฉันจะเขียนโปรแกรมจำลองเครื่องทัวริงที่เหมาะสมในภาษาที่พิมพ์แบบคงที่

เคล็ดลับกับระบบแบบสแตติกคือให้ความยืดหยุ่นที่เหมาะสมสำหรับกรณีที่ความยืดหยุ่นช่วยให้คุณสามารถเขียนโค้ดที่สามารถบำรุงรักษาได้ง่ายขึ้น

ต่อไปนี้เป็นตัวอย่างของเทคนิคการจัดโครงสร้างโปรแกรมที่บางครั้งคิดว่าง่ายต่อการจัดการในแบบไดนามิกมากกว่าภาษาที่พิมพ์แบบคงที่

ยาสามัญและภาชนะบรรจุ

ในภาษาที่พิมพ์แบบสแตติกก่อนML (c. 1973) และCLU (c. 1974) มันไม่ยากที่จะสร้างสายอักขระสีแดง - ดำต้นไม้ต้นแดง - ดำจำนวนเต็มต้นไม้สีแดง - ดำลอยหรือ Fooต้นไม้แดงดำขององค์ประกอบของประเภทที่เฉพาะเจาะจง อย่างไรก็ตามมันเป็นเรื่องยาก (อาจเป็นไปไม่ได้) ในการสร้างการใช้งานครั้งเดียวของต้นไม้สีแดงดำที่ถูกตรวจสอบทั้งแบบคงที่และสามารถจัดการกับชนิดข้อมูลใด ๆ เหล่านี้ได้ วิธีแก้ไขปัญหาคือ (1) แยกระบบประเภทออกมาอย่างสมบูรณ์ (ตัวอย่างเช่น: โดยใช้void * ใน C), (2) เขียนตัวประมวลผลมาโครตัวเองก่อนแล้วจึงเขียนมาโครที่สร้างรหัสสำหรับแต่ละประเภทที่คุณต้องการหรือ (3) ใช้วิธี Lisp / Smalltalk (และ Java) ในการตรวจสอบชนิดของสารสกัด วัตถุแบบไดนามิก

ML และ CLU แนะนำแนวคิดของประเภทพารามิเตอร์ตามลำดับ (แบบคงที่) ที่สรุปและประกาศอย่างชัดเจนซึ่งช่วยให้คุณสามารถเขียนประเภทคอนเทนเนอร์แบบทั่วไป

ความหลากหลายย่อย

ในภาษาที่พิมพ์แบบสแตติกก่อนSimula67 (c. 1967) และHope (c. 1977) มันเป็นไปไม่ได้ที่ทั้งสองจะทำการส่งข้อมูลแบบไดนามิกและตรวจสอบแบบคงที่ว่าคุณครอบคลุมทุกประเภทย่อย หลายภาษามีรูปแบบของสหภาพที่ติดแท็กบางรูปแบบแต่เป็นความรับผิดชอบของโปรแกรมเมอร์ที่จะต้องตรวจสอบให้แน่ใจว่าข้อความcaseหรือswitchข้อความหรือตารางการข้ามของพวกเขาครอบคลุมทุกแท็กที่เป็นไปได้

ภาษาตามโมเดล Simula (C ++, Java, C #, Eiffel) ให้คลาสนามธรรมพร้อมคลาสย่อยที่คอมไพเลอร์สามารถตรวจสอบว่าคลาสย่อยแต่ละคลาสใช้วิธีการทั้งหมดที่ประกาศโดยคลาสพาเรนต์ ภาษาที่ตามหลังโมเดลหวัง (ตัวแปร ML ทั้งหมดจาก SML / NJ ถึง Haskell) มีชนิดย่อยเชิงพีชคณิตที่คอมไพเลอร์สามารถตรวจสอบว่าทุกtypecaseคำสั่งครอบคลุมประเภทย่อยทั้งหมด

การปะแก้ของลิงและการเขียนโปรแกรมเชิงแนว

ระบบประเภทไดนามิกทำให้เทคนิคการสร้างต้นแบบที่หลากหลายง่ายขึ้นมาก ในภาษาที่ประเภทถูกแสดงด้วยแผนที่แฮชจากสตริงไปยังฟังก์ชั่น (เช่น Python, Javascript, Ruby) มันค่อนข้างง่ายที่จะเปลี่ยนพฤติกรรมของทุกโมดูลทั่วโลกที่อาศัยประเภทเฉพาะเพียงแค่ปรับเปลี่ยนแผนที่แบบไดนามิกที่แสดงว่า ชนิด

ในขณะที่มีวิธีการที่ชัดเจนในการใช้การปะแก้ลิงเพื่อทำให้โปรแกรมยากต่อการบำรุงรักษา แต่ก็มีวิธีที่มันสามารถใช้สำหรับ "ดี" จริง ๆ แทนที่จะเป็น "ความชั่วร้าย" โดยเฉพาะอย่างยิ่งกับการเขียนโปรแกรมที่มุ่งเน้นด้านหนึ่งสามารถใช้การปะของลิงเช่นเทคนิคในการทำสิ่งต่าง ๆ เช่นปรับเปลี่ยนชนิดไฟล์ให้ชี้ไปที่ระบบไฟล์เสมือนจริงอนุญาตให้สร้างโครงสร้างพื้นฐานการทดสอบหน่วยสำหรับ "ฟรี" หรือแก้ไขข้อยกเว้นแบบง่าย ๆ พิมพ์ข้อความบันทึกทุกครั้งที่ตรวจพบว่ามีการดีบั๊กได้ดีขึ้น

แตกต่างจาก Generics และ Subtype Polymorphism ที่แนวคิดการตรวจสอบแบบสแตติกที่สำคัญมีอยู่ในปี 1970 การตรวจสอบแบบคงที่สำหรับการเขียนโปรแกรมเชิงลักษณะคือ (ฉันคิดว่า) พื้นที่การวิจัยเชิงรุก ฉันไม่รู้อะไรมากเกี่ยวกับเรื่องนี้ยกเว้นว่ามีภาษาที่เรียกว่าAspectJมาตั้งแต่ปี 2544

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.