อะไรคือข้อดีและข้อ จำกัด ของภาษาประเภทไดนามิกเมื่อเทียบกับภาษาประเภทคงที่?
ดูเพิ่มเติม : อะไรกับความรักของภาษาแบบไดนามิก (หัวข้อโต้แย้งมากกว่า ... )
อะไรคือข้อดีและข้อ จำกัด ของภาษาประเภทไดนามิกเมื่อเทียบกับภาษาประเภทคงที่?
ดูเพิ่มเติม : อะไรกับความรักของภาษาแบบไดนามิก (หัวข้อโต้แย้งมากกว่า ... )
คำตอบ:
ความสามารถของล่ามในการอนุมานประเภทและประเภทการแปลงทำให้เวลาในการพัฒนาเร็วขึ้น แต่ยังสามารถกระตุ้นความล้มเหลวของรันไทม์ซึ่งคุณไม่สามารถรับในภาษาที่พิมพ์แบบคงที่ที่คุณจับพวกเขาในเวลารวบรวม แต่สิ่งที่คนที่ดีกว่า (หรือแม้ว่ามันจะเป็นจริงเสมอ) จะมีการพูดคุยกันอย่างถึงพริกถึงขิงในชุมชนทุกวันนี้ (และเป็นเวลานาน)
สิ่งที่ดีในเรื่องนี้ก็คือStatic Typing หากเป็นไปได้การพิมพ์แบบไดนามิกเมื่อต้องการ: สิ้นสุดสงครามเย็นระหว่างภาษาโปรแกรมโดย Erik Meijer และ Peter Drayton ที่ Microsoft:
ประชาสัมพันธ์การพิมพ์แบบคงที่ยืนยันว่าข้อดีของการพิมพ์แบบคงที่รวมถึงการตรวจสอบก่อนหน้านี้ของข้อผิดพลาดการเขียนโปรแกรม (เช่นการป้องกันการเพิ่มจำนวนเต็มบูลีน) เอกสารที่ดีกว่าในรูปแบบของลายเซ็นประเภท โอกาสสำหรับการเพิ่มประสิทธิภาพคอมไพเลอร์ (เช่นการเปลี่ยนการโทรเสมือนโดยการโทรโดยตรงเมื่อทราบชนิดที่แน่นอนของเครื่องรับแบบสแตติก) เพิ่มประสิทธิภาพรันไทม์ (เช่นค่าทั้งหมดไม่จำเป็นต้องพกแบบไดนามิก) และประสบการณ์การออกแบบที่ดีขึ้น ประเภทของเครื่องรับที่ IDE สามารถแสดงเมนูแบบเลื่อนลงของสมาชิกที่เกี่ยวข้องทั้งหมด) ผู้ชื่นชอบการพิมพ์แบบคงที่พยายามทำให้เราเชื่อว่า“ โปรแกรมที่พิมพ์ออกมาดีไม่สามารถผิดพลาดได้” ในขณะที่สิ่งนี้ฟังดูน่าประทับใจ มันเป็นคำสั่งที่ค่อนข้างว่างเปล่า การตรวจสอบชนิดสแตติกเป็นนามธรรมเวลารวบรวมของพฤติกรรมรันไทม์ของโปรแกรมของคุณและดังนั้นจึงจำเป็นต้องมีเพียงเสียงบางส่วนและไม่สมบูรณ์ ซึ่งหมายความว่าโปรแกรมยังคงสามารถทำงานผิดพลาดได้เนื่องจากคุณสมบัติที่ไม่ได้ติดตามโดยตัวตรวจสอบชนิดและมีโปรแกรมที่ในขณะที่ไม่สามารถทำงานผิดพลาดได้ไม่สามารถตรวจสอบชนิดได้ แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยกว่าและสมบูรณ์กว่าทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก การตรวจสอบชนิดสแตติกเป็นนามธรรมเวลารวบรวมของพฤติกรรมรันไทม์ของโปรแกรมของคุณและดังนั้นจึงจำเป็นต้องมีเพียงเสียงบางส่วนและไม่สมบูรณ์ ซึ่งหมายความว่าโปรแกรมยังคงสามารถทำงานผิดพลาดได้เนื่องจากคุณสมบัติที่ไม่ได้ติดตามโดยตัวตรวจสอบชนิดและมีโปรแกรมที่ในขณะที่ไม่สามารถทำงานผิดพลาดได้ไม่สามารถตรวจสอบชนิดได้ แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยกว่าและสมบูรณ์กว่าทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก การตรวจสอบชนิดสแตติกเป็นนามธรรมเวลารวบรวมของพฤติกรรมรันไทม์ของโปรแกรมของคุณและดังนั้นจึงจำเป็นต้องมีเพียงเสียงบางส่วนและไม่สมบูรณ์ ซึ่งหมายความว่าโปรแกรมยังคงสามารถทำงานผิดพลาดได้เนื่องจากคุณสมบัติที่ไม่ได้ติดตามโดยตัวตรวจสอบชนิดและมีโปรแกรมที่ในขณะที่ไม่สามารถทำงานผิดพลาดได้ไม่สามารถตรวจสอบชนิดได้ แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยกว่าและสมบูรณ์กว่าทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก และด้วยเหตุนี้จึงจำเป็นต้องมีเพียงเสียงบางส่วนและไม่สมบูรณ์ ซึ่งหมายความว่าโปรแกรมยังคงสามารถทำงานผิดพลาดได้เนื่องจากคุณสมบัติที่ไม่ได้ติดตามโดยตัวตรวจสอบชนิดและมีโปรแกรมที่ในขณะที่ไม่สามารถทำงานผิดพลาดได้ไม่สามารถตรวจสอบชนิดได้ แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยลงและสมบูรณ์มากขึ้นทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก และด้วยเหตุนี้จึงจำเป็นต้องมีเพียงเสียงบางส่วนและไม่สมบูรณ์ ซึ่งหมายความว่าโปรแกรมยังคงสามารถทำงานผิดพลาดได้เนื่องจากคุณสมบัติที่ไม่ได้ติดตามโดยตัวตรวจสอบชนิดและมีโปรแกรมที่ในขณะที่ไม่สามารถทำงานผิดพลาดได้ไม่สามารถตรวจสอบชนิดได้ แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยลงและสมบูรณ์มากขึ้นทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก และมีโปรแกรมที่ในขณะที่พวกเขาไม่ผิดพลาดไม่สามารถตรวจสอบประเภท แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยลงและสมบูรณ์มากขึ้นทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก และมีโปรแกรมที่ในขณะที่พวกเขาไม่ผิดพลาดไม่สามารถตรวจสอบประเภท แรงกระตุ้นสำหรับการพิมพ์แบบสแตติกน้อยลงและสมบูรณ์มากขึ้นทำให้ระบบประเภทมีความซับซ้อนและแปลกใหม่มากเกินกว่าจะเห็นได้จากแนวคิดเช่น "phantom types" [11] และ "wobbly types" [10] นี่เหมือนกับการพยายามวิ่งมาราธอนโดยมีลูกบอลและโซ่ผูกติดอยู่กับขาของคุณและตะโกนอย่างมีชัยชนะว่าคุณเกือบทำมันแม้ว่าคุณจะถูกประกันตัวหลังจากไมล์แรก
ประชาสัมพันธ์ภาษาที่พิมพ์แบบไดนามิกยืนยันว่าการพิมพ์แบบสแตติกนั้นเข้มงวดเกินไปและความนุ่มนวลของภาษาแบบไดนามิกทำให้เหมาะสำหรับระบบการสร้างต้นแบบที่มีข้อกำหนดที่เปลี่ยนแปลงหรือไม่ทราบหรือมีปฏิสัมพันธ์กับระบบอื่น ๆ ที่เปลี่ยนแปลงไม่อาจคาดเดาได้ แน่นอนว่าภาษาที่พิมพ์แบบไดนามิกนั้นเป็นสิ่งที่ขาดไม่ได้ในการจัดการกับพฤติกรรมของโปรแกรมแบบไดนามิกอย่างแท้จริงเช่นการสกัดกั้นวิธีการโหลดแบบไดนามิกโค้ดมือถือการสะท้อนกลับในเวลาทำงานเป็นต้นในแม่ของเอกสารทั้งหมดในการเขียนสคริปต์ [16] ภาษาการเขียนโปรแกรมทำให้โค้ดที่นำมาใช้ซ้ำได้น้อยลง, verbose มากขึ้น, ไม่ปลอดภัยมากขึ้นและแสดงออกน้อยกว่าภาษาสคริปต์ที่พิมพ์แบบไดนามิก อาร์กิวเมนต์นี้ถูกทำให้เป็นเรื่องจริงโดยผู้เสนอหลายภาษาสคริปต์แบบไดนามิก เรายืนยันว่านี่เป็นความเข้าใจผิดและตกอยู่ในประเภทเดียวกันกับการโต้แย้งว่าสาระสำคัญของการเขียนโปรแกรมเชิงประกาศกำลังกำจัดการมอบหมาย หรืออย่างที่ John Hughes พูด [8] มันเป็นไปไม่ได้ที่จะทำให้ภาษามีประสิทธิภาพมากขึ้นโดยการไม่ใช้ฟีเจอร์ การปกป้องความจริงที่ว่าการหน่วงเวลาการตรวจสอบชนิดทั้งหมดไปยังรันไทม์เป็นสิ่งที่ดีกำลังเล่นยุทธวิธีนกกระจอกเทศด้วยความจริงที่ว่าข้อผิดพลาดควรถูกจับได้เร็วที่สุดในกระบวนการพัฒนาเท่าที่จะทำได้ มันเป็นไปไม่ได้ที่จะทำให้ภาษามีประสิทธิภาพมากขึ้นโดยการละเว้นคุณสมบัติ การปกป้องความจริงที่ว่าการหน่วงเวลาการตรวจสอบชนิดทั้งหมดไปยังรันไทม์เป็นสิ่งที่ดีกำลังเล่นยุทธวิธีนกกระจอกเทศด้วยความจริงที่ว่าข้อผิดพลาดควรถูกจับได้เร็วที่สุดในกระบวนการพัฒนาเท่าที่จะทำได้ มันเป็นไปไม่ได้ที่จะทำให้ภาษามีประสิทธิภาพมากขึ้นโดยการละเว้นคุณสมบัติ การปกป้องความจริงที่ว่าการหน่วงเวลาการตรวจสอบชนิดทั้งหมดไปยังรันไทม์เป็นสิ่งที่ดีกำลังเล่นยุทธวิธีนกกระจอกเทศด้วยความจริงที่ว่าข้อผิดพลาดควรถูกจับได้เร็วที่สุดในกระบวนการพัฒนาเท่าที่จะทำได้
ระบบชนิดคงที่พยายามกำจัดข้อผิดพลาดบางอย่างแบบคงที่ตรวจสอบโปรแกรมโดยไม่เรียกใช้และพยายามพิสูจน์ความสมบูรณ์ในบางประการ ระบบพิมพ์บางประเภทสามารถตรวจจับข้อผิดพลาดได้มากกว่าระบบอื่น ๆ ตัวอย่างเช่น C # สามารถกำจัดข้อยกเว้นตัวชี้โมฆะเมื่อใช้อย่างถูกต้องในขณะที่ Java ไม่มีพลังงานเช่นนั้น Twelf มีระบบการพิมพ์ที่จริงรับประกันได้ว่าจะยุติการพิสูจน์ "แก้" ความลังเลปัญหา
อย่างไรก็ตามระบบประเภทไม่สมบูรณ์แบบ เพื่อที่จะกำจัดข้อผิดพลาดระดับหนึ่งพวกเขาจะต้องปฏิเสธโปรแกรมที่ใช้ได้อย่างสมบูรณ์ซึ่งละเมิดกฎ นี่คือสาเหตุที่ Twelf ไม่ได้แก้ปัญหาการหยุดชะงักจริง ๆ เพียงแค่หลีกเลี่ยงโดยการโยนหลักฐานพิสูจน์ที่สมบูรณ์แบบจำนวนมากซึ่งเกิดขึ้นเพื่อยุติในรูปแบบแปลก ๆ ในทำนองเดียวกันระบบประเภทของ Java ปฏิเสธPersistentVector
การใช้งานของ Clojure เนื่องจากการใช้อาร์เรย์ที่ต่างกัน มันทำงานได้ที่ runtime แต่ระบบ type ไม่สามารถตรวจสอบได้
ด้วยเหตุผลดังกล่าวระบบประเภทส่วนใหญ่จึงจัดเตรียม "escapes" วิธีการแทนที่ตัวตรวจสอบแบบคงที่ สำหรับภาษาส่วนใหญ่สิ่งเหล่านี้อยู่ในรูปแบบของการคัดเลือกนักแสดงบางคน (เช่น C # และ Haskell) มีโหมดทั้งหมดซึ่งระบุว่า "ไม่ปลอดภัย"
ฉันชอบการพิมพ์แบบคงที่ในใจ มีการใช้งานอย่างถูกต้อง (คำแนะนำ: ไม่ใช่ Java) ระบบชนิดสแตติกสามารถช่วยได้มากในการกำจัดข้อผิดพลาดก่อนที่ระบบจะทำงานผิดพลาด ภาษาที่พิมพ์แบบไดนามิกมักจะต้องใช้การทดสอบหน่วยเพิ่มเติมซึ่งน่าเบื่อในเวลาที่ดีที่สุด นอกจากนี้ภาษาที่พิมพ์แบบคงที่สามารถมีคุณสมบัติบางอย่างที่เป็นไปไม่ได้หรือไม่ปลอดภัยในระบบประเภทไดนามิก ( การแปลงโดยนัยเป็นสิ่งสำคัญ) มันเป็นคำถามของความต้องการและรสนิยมส่วนตัว ฉันจะไม่สร้าง Eclipse ถัดไปใน Ruby มากกว่าฉันจะพยายามเขียนสคริปต์สำรองใน Assembly หรือ patch kernel โดยใช้ Java
โอ้และคนที่พูดว่า "การพิมพ์xมีประสิทธิภาพมากกว่าการพิมพ์y 10 เท่า" เป็นเพียงการเป่าควัน พิมพ์แบบไดนามิกอาจ "รู้สึก" ได้เร็วขึ้นในหลายกรณี แต่จะสูญเสียพื้นดินเมื่อคุณจริงพยายามที่จะทำให้จินตนาการของคุณแอพลิเคชันการทำงาน ในทำนองเดียวกันการพิมพ์แบบคงที่อาจดูเหมือนว่ามันเป็นเครือข่ายความปลอดภัยที่สมบูรณ์แบบ แต่เพียงครั้งเดียวดูที่คำจำกัดความประเภททั่วไปที่ซับซ้อนมากขึ้นใน Java ส่งนักพัฒนาส่วนใหญ่เผ่นหนีตาตาบอด แม้จะใช้ระบบพิมพ์และผลิตภาพ แต่ก็ไม่มีกระสุนเงิน
หมายเหตุสุดท้าย: ไม่ต้องกังวลเกี่ยวกับประสิทธิภาพเมื่อเปรียบเทียบกับการพิมพ์แบบไดนามิก JIT สมัยใหม่เช่น V8 และ TraceMonkey กำลังมาใกล้อันตรายกับการใช้ภาษาแบบคงที่ นอกจากนี้ความจริงที่ว่า Java รวบรวมภาษาเป็นสื่อกลางแบบไดนามิกโดยเนื้อแท้ควรจะเป็นคำใบ้ว่าสำหรับกรณีส่วนใหญ่การพิมพ์แบบไดนามิกไม่ใช่นักฆ่าประสิทธิภาพขนาดใหญ่ที่บางคนทำให้เป็น
dadd
เพราะเขารู้ล่วงหน้าว่าตัวถูกดำเนินการเป็นdouble
s
ทั้งสองคนเข้าใจผิดกันมากและมีสองสิ่งที่แตกต่างกันโดยสิ้นเชิง ที่ไม่ได้พิเศษร่วมกัน
ประเภทคงที่เป็นข้อ จำกัด ของไวยากรณ์ของภาษา ภาษาอังกฤาที่พิมพ์แบบคงที่อาจกล่าวได้ว่าไม่ใช่บริบทฟรี ความจริงง่ายๆคือมันไม่สะดวกที่จะแสดงภาษาอย่างฉลาดในบริบทของไวยากรณ์ฟรีที่ไม่ได้ใช้ข้อมูลทั้งหมดเป็นเพียงเวกเตอร์บิต ระบบชนิดสแตติกเป็นส่วนหนึ่งของไวยากรณ์ของภาษาหากมีพวกเขา จำกัด มันมากกว่าบริบทไวยากรณ์ฟรีสามารถตรวจสอบไวยากรณ์จึงเกิดขึ้นในสองผ่านมากกว่าแหล่งที่มาจริง ประเภทสถิตสอดคล้องกับความคิดทางคณิตศาสตร์ของทฤษฎีประเภททฤษฎีประเภทในวิชาคณิตศาสตร์ จำกัด เพียงความถูกต้องตามกฎหมายของการแสดงออกบางอย่าง เช่นฉันไม่สามารถพูด3 + [4,7]
ในวิชาคณิตศาสตร์นี่เป็นเพราะทฤษฎีประเภทของมัน
ประเภทสแตติกจึงไม่ใช่วิธีการ 'ป้องกันข้อผิดพลาด' จากมุมมองทางทฤษฎี แต่เป็นข้อ จำกัด ของไวยากรณ์ แน่นอนว่า +, 3 และช่วงเวลามีข้อกำหนดทางทฤษฎีชุดปกติถ้าเราลบระบบประเภทที่3 + [4,7]
มีผลลัพธ์ที่กำหนดไว้ค่อนข้างดีนั่นคือชุด ในทางทฤษฎีไม่มีข้อผิดพลาด 'runtime error type' การใช้งานจริงของระบบประเภทนี้คือการป้องกันการดำเนินการที่มนุษย์ไม่ควรทำ การดำเนินการยังคงเป็นเพียงแค่การเปลี่ยนและจัดการบิตเท่านั้น
สิ่งที่จับได้คือระบบประเภทไม่สามารถตัดสินใจได้ว่าการดำเนินการดังกล่าวจะเกิดขึ้นหรือไม่หากได้รับอนุญาตให้เรียกใช้ เช่นเดียวกับในพาร์ทิชันชุดของโปรแกรมที่เป็นไปได้ทั้งหมดในผู้ที่จะมี 'ข้อผิดพลาดประเภท' และผู้ที่ไม่ได้ สามารถทำได้สองสิ่งเท่านั้น:
1: พิสูจน์ว่าข้อผิดพลาดประเภทจะเกิดขึ้นในโปรแกรม
2: พิสูจน์ว่าพวกเขาจะไม่เกิดขึ้นในโปรแกรม
นี่อาจดูเหมือนว่าฉันขัดแย้งกับตัวเอง แต่สิ่งที่ตัวตรวจสอบชนิด C หรือ Java ทำคือปฏิเสธโปรแกรมเป็น 'ungrammatical' หรือที่เรียกว่า 'ข้อผิดพลาดชนิด' หากไม่สามารถสำเร็จได้ที่ 2 ไม่สามารถพิสูจน์ได้ว่าจะไม่เกิดขึ้น นั่นไม่ได้หมายความว่าพวกเขาจะไม่เกิดขึ้นมันก็หมายความว่ามันไม่สามารถพิสูจน์ได้ อาจเป็นไปได้ว่าโปรแกรมที่ไม่มีข้อผิดพลาดประเภทนั้นถูกปฏิเสธเพียงเพราะคอมไพเลอร์ไม่สามารถพิสูจน์ได้ ตัวอย่างง่ายๆif(1) a = 3; else a = "string";
แน่นอนเนื่องจากเป็นจริงเสมอส่วนอื่นจะไม่ถูกดำเนินการในโปรแกรมและจะไม่มีข้อผิดพลาดประเภทเกิดขึ้น แต่มันไม่สามารถพิสูจน์กรณีเหล่านี้ในลักษณะทั่วไปดังนั้นจึงถูกปฏิเสธ นี่คือจุดอ่อนหลักของภาษาที่พิมพ์แบบคงที่จำนวนมากในการปกป้องคุณจากตัวคุณเองคุณจำเป็นต้องได้รับการปกป้องในกรณีที่คุณไม่ต้องการ
แต่ตรงกันข้ามกับความเชื่อที่ได้รับความนิยมนอกจากนี้ยังมีภาษาที่พิมพ์แบบคงที่ที่ทำงานตามหลักการที่ 1 พวกเขาเพียงปฏิเสธโปรแกรมทั้งหมดที่พวกเขาสามารถพิสูจน์ได้ว่ามันจะทำให้เกิดข้อผิดพลาดประเภทและผ่านโปรแกรมทั้งหมดที่พวกเขาไม่สามารถ ดังนั้นจึงเป็นไปได้ที่พวกเขาจะอนุญาตให้โปรแกรมที่มีข้อผิดพลาดในการพิมพ์เป็นตัวอย่างที่ดีในการพิมพ์แร็กเก็ตมันเป็นลูกผสมระหว่างการพิมพ์แบบไดนามิกและแบบคงที่ และบางคนก็แย้งว่าคุณได้สิ่งที่ดีที่สุดทั้งสองโลกในระบบนี้
ข้อดีอีกประการของการพิมพ์แบบสแตติกก็คือชนิดนั้นจะรู้จักกันในเวลารวบรวมและทำให้คอมไพเลอร์สามารถใช้สิ่งนี้ได้ หากเราใน Java ทำ"string" + "string"
หรือ3 + 3
ทั้งสอง+
โทเค็นในข้อความในตอนท้ายเป็นตัวแทนของการดำเนินงานที่แตกต่างกันอย่างสมบูรณ์และข้อมูลที่รวบรวมเรียบรู้ที่จะเลือกจากประเภทเดียว
ตอนนี้ผมกำลังจะไปทำคำสั่งที่ถกเถียงกันมากที่นี่ แต่หมีกับฉัน: 'พิมพ์แบบไดนามิก' ไม่มีอยู่
เสียงขัดแย้งมาก แต่มันเป็นความจริงภาษาพิมพ์แบบไดนามิกจากมุมมองทางทฤษฎีuntyped พวกเขาเป็นเพียงภาษาที่พิมพ์แบบคงที่มีเพียงหนึ่งประเภท หรือพูดง่ายๆก็คือพวกเขาเป็นภาษาที่สร้างขึ้นตามหลักไวยากรณ์อย่างแท้จริงจากบริบทที่ปราศจากไวยากรณ์ในทางปฏิบัติ
ทำไมพวกเขาไม่มีประเภท? เนื่องจากการดำเนินการทุกครั้งได้รับการกำหนดและอนุญาตให้ใช้กับผู้ปฏิบัติงานทุกคน 'ข้อผิดพลาดประเภท runtime' คืออะไร มันมาจากตัวอย่างทฤษฎีหมดจดผลข้างเคียง หากทำprint("string")
สิ่งที่พิมพ์สตริงเป็นการดำเนินการดังนั้นlength(3)
ในอดีตจะมีผลข้างเคียงของการเขียนstring
ไปยังเอาต์พุตมาตรฐานอย่างหลังerror: function 'length' expects array as argument.
นั่นคือมัน จากมุมมองทางทฤษฎีไม่มีสิ่งใดเป็นภาษาที่พิมพ์แบบไดนามิก พวกเขาจะuntyped
เอาล่ะข้อได้เปรียบที่ชัดเจนของภาษา 'ที่พิมพ์แบบไดนามิก' คือพลังแห่งการแสดงออกระบบประเภทคืออะไร แต่เป็นข้อ จำกัด ของพลังที่แสดงออก และโดยทั่วไปภาษาที่มีระบบพิมพ์จะมีผลลัพธ์ที่กำหนดไว้สำหรับการดำเนินการทั้งหมดที่ไม่ได้รับอนุญาตหากระบบประเภทนั้นเพิ่งถูกเพิกเฉยผลลัพธ์จะไม่สมเหตุสมผลกับมนุษย์ หลายภาษาสูญเสียความสมบูรณ์ของทัวริงหลังจากใช้ระบบพิมพ์
ข้อเสียที่เห็นได้ชัดคือความจริงที่ว่าการดำเนินการสามารถเกิดขึ้นได้ซึ่งจะสร้างผลลัพธ์ที่ไร้สาระต่อมนุษย์ เพื่อป้องกันสิ่งนี้ภาษาที่พิมพ์แบบไดนามิกโดยทั่วไปจะกำหนดการดำเนินการเหล่านั้นใหม่แทนที่จะสร้างผลลัพธ์ที่ไร้สาระที่พวกเขากำหนดใหม่ให้มีผลข้างเคียงของการเขียนข้อผิดพลาดและอาจหยุดโปรแกรมโดยสิ้นเชิง นี่ไม่ใช่ข้อผิดพลาด แต่อย่างใดในความเป็นจริงข้อกำหนดทางภาษามักแสดงถึงสิ่งนี้นี่เป็นพฤติกรรมของภาษามากเท่ากับการพิมพ์สตริงจากมุมมองเชิงทฤษฎี ระบบประเภทจึงบังคับให้โปรแกรมเมอร์ให้เหตุผลเกี่ยวกับการไหลของรหัสเพื่อให้แน่ใจว่าสิ่งนี้จะไม่เกิดขึ้น หรือเหตุผลจริงๆเพื่อที่จะทำการเกิดขึ้นอาจมีประโยชน์ในบางจุดสำหรับการดีบักซึ่งแสดงว่าไม่ใช่ 'ข้อผิดพลาด' เลย แต่เป็นคุณสมบัติที่กำหนดไว้อย่างดีของภาษา ผลที่เหลืออยู่เพียงครั้งเดียวของ 'การพิมพ์แบบไดนามิก' ที่ภาษาส่วนใหญ่มีคือการป้องกันการหารด้วยศูนย์ นี่คือสิ่งที่การพิมพ์แบบไดนามิกคือไม่มีประเภทไม่มีประเภทมากกว่าศูนย์ที่เป็นประเภทที่แตกต่างจากตัวเลขอื่น ๆ ทั้งหมด สิ่งที่ผู้คนเรียกว่า 'type' เป็นเพียงคุณสมบัติของ datum เช่นความยาวของอาเรย์หรืออักขระตัวแรกของสตริง "error: the first character of this string should be a 'z'"
และอีกหลายภาษาพิมพ์แบบไดนามิกยังช่วยให้คุณสามารถเขียนออกสิ่งที่ชอบ
อีกสิ่งหนึ่งคือภาษาที่พิมพ์แบบไดนามิกมีชนิดที่มีให้ใช้งานที่รันไทม์และมักจะสามารถตรวจสอบและจัดการกับมันและตัดสินใจจากมัน แน่นอนว่าในทางทฤษฎีแล้วมันไม่ต่างไปจากการเข้าถึงตัวอักษรตัวแรกของอาร์เรย์และดูว่ามันคืออะไร ในความเป็นจริงคุณสามารถสร้าง C ไดนามิกของคุณเองเพียงแค่ใช้ชนิดเดียวเช่น long long int และใช้ 8 บิตแรกเพื่อเก็บ 'type' ของคุณและเขียนฟังก์ชันตามที่ตรวจสอบและดำเนินการเพิ่มหรือจำนวนเต็ม คุณมีภาษาที่พิมพ์แบบคงที่ด้วยหนึ่งประเภทหรือภาษาแบบไดนามิก
ในทางปฏิบัติสิ่งนี้แสดงให้เห็นว่าภาษาที่พิมพ์แบบคงที่มักใช้ในบริบทของการเขียนซอฟต์แวร์เชิงพาณิชย์ในขณะที่ภาษาที่พิมพ์แบบไดนามิกมักจะถูกนำมาใช้ในบริบทของการแก้ปัญหาและทำให้งานบางอย่างเป็นไปโดยอัตโนมัติ การเขียนโค้ดในภาษาที่พิมพ์แบบคงที่นั้นใช้เวลานานและยุ่งยากเพราะคุณไม่สามารถทำสิ่งต่าง ๆ ที่คุณรู้ว่าจะกลายเป็นเรื่องปกติ แต่ระบบประเภทยังปกป้องคุณจากข้อผิดพลาดที่คุณไม่ได้ทำ โคเดอร์หลายคนไม่ทราบว่าพวกเขาทำเช่นนี้เพราะมันอยู่ในระบบของพวกเขา แต่เมื่อคุณเขียนโค้ดในภาษาแบบสแตติกคุณมักจะหลีกเลี่ยงความจริงที่ว่าระบบประเภทจะไม่ยอมให้คุณทำสิ่งที่ผิดพลาด ไม่สามารถพิสูจน์ได้ว่าจะไม่ผิด
ดังที่ฉันได้ระบุไว้ว่า 'การพิมพ์แบบคงที่' โดยทั่วไปหมายถึงกรณีที่ 2 มีความผิดจนกว่าจะพิสูจน์ได้ว่าไร้เดียงสา แต่ภาษาบางภาษาซึ่งไม่ได้มาจากระบบการพิมพ์ของพวกเขาจากทฤษฎีประเภทที่ทุกคนใช้กฎที่ 1: ผู้บริสุทธิ์จนกว่าจะพิสูจน์ความผิดซึ่งอาจเป็นไฮบริดที่เหมาะ ดังนั้นบางที Typed Racket ก็เหมาะสำหรับคุณ
นอกจากนี้สำหรับตัวอย่างที่ไร้สาระและมากขึ้นฉันกำลังใช้ภาษาที่ 'ประเภท' เป็นอักขระตัวแรกของอาร์เรย์อย่างแท้จริงพวกมันคือข้อมูลข้อมูลของ 'ชนิด' 'ชนิด' ซึ่งเป็นตัวของมันเอง ประเภทและ datum เฉพาะตัวเลขที่มีตัวเองเป็นประเภท ประเภทไม่ จำกัด หรือมีขอบเขตแบบคงที่ แต่อาจมีชนิดใหม่ที่สร้างขึ้นตามข้อมูลรันไทม์
บางทีประโยชน์ที่ใหญ่ที่สุดของการพิมพ์แบบไดนามิกอาจเป็นช่วงการเรียนรู้ที่ตื้นกว่า ไม่มีระบบการพิมพ์ที่จะเรียนรู้และไม่มีไวยากรณ์ที่ไม่สำคัญสำหรับกรณีมุมเช่นข้อ จำกัด ประเภท ทำให้ผู้คนจำนวนมากสามารถเข้าถึงการพิมพ์แบบไดนามิกและเป็นไปได้สำหรับคนจำนวนมากที่ระบบพิมพ์แบบคงที่ที่ซับซ้อนอยู่ไกลเกินเอื้อม ดังนั้นการพิมพ์แบบไดนามิกได้ติดอยู่ในบริบทของการศึกษา (เช่น Scheme / Python ที่ MIT) และภาษาเฉพาะโดเมนสำหรับผู้ที่ไม่ใช่โปรแกรมเมอร์ (เช่นMathematica ) ภาษาไดนามิกยังติดอยู่ในซอกที่พวกเขามีการแข่งขันน้อยหรือไม่มีเลย (เช่น Javascript)
ภาษาที่พิมพ์แบบไดนามิกที่กระชับที่สุด (เช่น Perl, APL, J, K, Mathematica ) เป็นโดเมนที่เฉพาะเจาะจงและสามารถกระชับได้มากกว่าภาษาที่ใช้ในการพิมพ์แบบคงที่ทั่วไป (เช่นOCaml ) ในภาษาที่พวกเขาออกแบบมาสำหรับ .
ข้อเสียเปรียบหลักของการพิมพ์แบบไดนามิกคือ:
ข้อผิดพลาดประเภทเวลาทำงาน
อาจเป็นเรื่องยากมากหรือเป็นไปไม่ได้ในทางปฏิบัติเพื่อให้ได้ระดับความถูกต้องเท่ากันและต้องการการทดสอบที่มากขึ้น
ไม่มีเอกสารที่ผ่านการตรวจสอบคอมไพเลอร์
ประสิทธิภาพไม่ดี (โดยปกติจะเป็นเวลาทำงาน แต่บางครั้งอาจใช้เวลาในการคอมไพล์แทนเช่นโครงการสตาลิน) และประสิทธิภาพที่คาดการณ์ไม่ได้เนื่องจากต้องพึ่งพาการปรับให้เหมาะสมที่ซับซ้อน
โดยส่วนตัวแล้วฉันเติบโตมากับภาษาแบบไดนามิก แต่จะไม่แตะต้องพวกเขาด้วยเสา 40 'ในฐานะมืออาชีพเว้นแต่จะไม่มีตัวเลือกอื่น ๆ
จากการพิมพ์ของ Artima : Strong vs. Weak,บทความStatic และ Dynamic
การพิมพ์ที่แข็งแกร่งช่วยป้องกันการผสมระหว่างประเภทที่ไม่ตรงกัน ในการผสมประเภทคุณต้องใช้การแปลงที่ชัดเจน
การพิมพ์ที่อ่อนแอหมายความว่าคุณสามารถผสมประเภทได้โดยไม่ต้องมีการแปลงที่ชัดเจน
ในกระดาษของ Pascal Costanza, Dynamic กับ Static Typing - การวิเคราะห์ตามรูปแบบ (PDF) เขาอ้างว่าในบางกรณีการพิมพ์แบบสแตติกนั้นมีข้อผิดพลาดมากกว่าการพิมพ์แบบไดนามิก ภาษาที่พิมพ์แบบคงที่บางภาษาบังคับให้คุณจำลองการพิมพ์แบบไดนามิกด้วยตนเองเพื่อทำ "สิ่งที่ถูกต้อง" มันกล่าวถึงในที่แลมบ์ดาสุดยอด
ขึ้นอยู่กับบริบท มีประโยชน์มากมายที่เหมาะสมกับระบบการพิมพ์แบบไดนามิกเช่นเดียวกับการพิมพ์ที่แข็งแกร่ง ฉันคิดว่าการไหลของภาษาประเภทไดนามิกเร็วขึ้น ภาษาแบบไดนามิกไม่ได้ถูก จำกัด ด้วยคุณสมบัติคลาสและความคิดคอมไพเลอร์ของสิ่งที่เกิดขึ้นในรหัส คุณมีอิสระ นอกจากนี้ภาษาแบบไดนามิกมักจะแสดงออกและส่งผลให้รหัสน้อยซึ่งเป็นสิ่งที่ดี แม้จะมีสิ่งนี้ แต่ก็มีข้อผิดพลาดมากกว่าซึ่งเป็นปัญหาและขึ้นอยู่กับการทดสอบหน่วยครอบคลุม มันเป็นเครื่องต้นแบบที่ใช้งานง่ายด้วยค่าไดนามิก แต่การบำรุงรักษาอาจกลายเป็นฝันร้าย
กำไรหลักจากระบบที่พิมพ์แบบคงที่คือการสนับสนุน IDE และการวิเคราะห์แบบคงที่ของรหัส คุณมีความมั่นใจในรหัสมากขึ้นหลังจากเปลี่ยนรหัสทุกครั้ง การบำรุงรักษาคือความสงบของเค้กด้วยเครื่องมือดังกล่าว
มีหลายสิ่งที่แตกต่างกันเกี่ยวกับภาษาแบบคงที่และแบบไดนามิก สำหรับฉันความแตกต่างที่สำคัญคือในภาษาแบบไดนามิกตัวแปรไม่มีชนิดคงที่ แต่ประเภทจะเชื่อมโยงกับค่าแทน ด้วยเหตุนี้รหัสที่แน่นอนที่ได้รับการดำเนินการจะถูกบึกบึนจนกว่ารันไทม์
ในช่วงต้นหรือการใช้งานที่ไม่ จำกัด นี่เป็นการลากประสิทธิภาพที่ยอดเยี่ยม แต่ JIT ที่ทันสมัยได้ใกล้เคียงกับสิ่งที่ดีที่สุดที่คุณจะได้รับจากการปรับแต่งคอมไพเลอร์ให้เหมาะสม (ในบางกรณียิ่งดีกว่านั้น)
มันคือทั้งหมดที่เกี่ยวกับเครื่องมือที่เหมาะสมสำหรับงาน ไม่ดีกว่า 100% ของเวลา ทั้งสองระบบถูกสร้างขึ้นโดยมนุษย์และมีข้อบกพร่อง ขออภัยเราดูดและทำสิ่งที่สมบูรณ์แบบ
ฉันชอบการพิมพ์แบบไดนามิกเพราะมันไปไม่ได้ แต่ใช่ข้อผิดพลาดรันไทม์สามารถคลานขึ้นที่ฉันไม่ได้วางแผน ในกรณีที่การพิมพ์แบบคงที่อาจแก้ไขข้อผิดพลาดดังกล่าว แต่ขับสามเณร (ในภาษาที่พิมพ์) โปรแกรมเมอร์บ้าพยายามที่จะโยนระหว่างถ่านคงที่และสตริง
พิมพ์ดีดคงที่: ภาษาเช่น Java และ Scala เป็นแบบคงที่พิมพ์
ตัวแปรจะต้องมีการกำหนดและเริ่มต้นก่อนที่จะใช้ในรหัส
สำหรับอดีต int x; x = 10;
System.out.println (x);
Dynamic Typing: Perl เป็นภาษาที่พิมพ์แบบไดนามิก
ตัวแปรไม่จำเป็นต้องเริ่มต้นก่อนที่จะใช้ในรหัส
การ y = 10; ใช้ตัวแปรนี้ในส่วนของรหัสในภายหลัง