การพิมพ์แบบคงที่คุ้มค่ากับการแลกเปลี่ยนหรือไม่?


108

ฉันเริ่มเขียนโปรแกรมด้วยภาษา Python เป็นหลักโดยที่ไม่มีความปลอดภัยประเภทจากนั้นย้ายไปที่ C # และ Java ที่มี ฉันพบว่าฉันสามารถทำงานได้เร็วขึ้นและปวดหัวน้อยลงใน Python แต่จากนั้นอีกครั้งแอป C # และ Java ของฉันมีระดับความซับซ้อนที่สูงขึ้นมากดังนั้นฉันจึงไม่เคยให้ Python เป็นการทดสอบความเครียดที่แท้จริง

ค่าย Java และ C # ทำให้ดูเหมือนไม่มีความปลอดภัยในสถานที่ที่คนส่วนใหญ่จะทำงานในทุกประเภทของข้อผิดพลาดที่น่ากลัวทิ้งขวาและมันจะมีปัญหามากกว่ามูลค่าของมัน

นี่ไม่ใช่การเปรียบเทียบภาษาดังนั้นโปรดอย่าแก้ไขปัญหาเช่นรวบรวมและตีความ ความปลอดภัยของประเภทคุ้มค่าต่อการพัฒนาและความยืดหยุ่นหรือไม่? ทำไม?

สำหรับผู้ที่ต้องการตัวอย่างของความคิดเห็นที่การพิมพ์แบบไดนามิกเร็วกว่า:

"ใช้ภาษาที่พิมพ์แบบไดนามิกในระหว่างการพัฒนาซึ่งจะช่วยให้คุณได้รับข้อเสนอแนะเวลาตอบสนองและความเร็วในการพัฒนาที่เร็วขึ้น" - http://blog.jayway.com/2010/04/14/static-typing-is-the-root-of-all-evil/


15
คำถามนี้เป็นสิ่งที่ตรงกันข้ามกับข้อโต้แย้งอะไรในความโปรดปรานของการพิมพ์ที่อ่อนแอ? .
Nicole

8
@Prof Plum: ฉันขอหลักฐานที่มีความเร็วในการพัฒนาและความยืดหยุ่นได้หรือไม่? เนื่องจากเรากำลังพูดถึงแง่มุมที่เฉพาะเจาะจงเกี่ยวกับประเภทความปลอดภัยการใช้งานJavaหรือC#ไม่สามารถสรุปได้วิธีของพวกเขาในการให้บริการไม่ใช่หนึ่งเดียว ...
Matthieu M.

32
ด้วยความขยันในภาษาที่เข้มงวดคุณสามารถลด "อาการปวดหัว" และจากนั้นคุณอาจเห็นการเพิ่มความเร็วเนื่องจากการเติมข้อมูลอัตโนมัติ IDE การสร้างรหัสและคำใบ้รหัส
นิโคล

9
@Prof Plum: ฉันเข้าใจว่าฉันไม่ได้คาดหวังว่าคุณ (หรือใครก็ตาม) ที่จะทดสอบอย่างเต็มที่ทุกภาษาที่เคยสร้างมา ^^ ปัญหาคือคนส่วนใหญ่ที่ฉันเคยเห็นบ่นเกี่ยวกับลักษณะเฉพาะบางประการของภาษาโปรแกรม (คงที่) การพิมพ์มักจะมา) โดยทั่วไปบ่นเกี่ยวกับการใช้งานเฉพาะและล้มเหลวในการรับรู้
Matthieu M.

5
@Prof Plum ทั้งหมดที่โพสต์ในบล็อกพูดถึงความเร็วคือการยืนยันหัวล้าน "ใครก็ตามที่ทำงานอย่างจริงจังกับภาษาที่พิมพ์แบบไดนามิกที่ทันสมัยเช่น Ruby หรือ Smalltalk รู้ว่าพวกเขามีประสิทธิผลมากกว่า" ไม่มีตัวอย่างที่แท้จริงของวิธีในแง่การปฏิบัติมันทำให้การพัฒนาเร็วขึ้น
Carson63000

คำตอบ:


162

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

ในภาษาที่พิมพ์แบบไดนามิก:

  • คุณยังต้องรู้ว่าคุณกำลังทำงานกับอาร์เรย์จำนวนเต็มสตริงสตริงตารางแฮชการอ้างอิงฟังก์ชันพจนานุกรมวัตถุหรืออะไรก็ตาม

  • ถ้าเป็นวัตถุคุณต้องรู้ว่ามันเป็นคลาสอะไร

  • การกำหนดหนึ่งในประเภทเหล่านี้ให้กับตัวแปรหรือฟังก์ชันพารามิเตอร์ที่คาดว่าจะเป็นประเภทอื่นมักจะเป็นข้อผิดพลาด

  • ในระดับที่ต่ำกว่าสิ่งต่าง ๆ เช่นจำนวนบิตหรือการลงชื่อเมื่อเทียบกับที่ไม่ได้ลงชื่อบ่อยครั้งยังคงต้องถูกนำมาใช้หากคุณกำลังเติมแพ็กเก็ต TCP เช่น

  • คุณสามารถพบปัญหาที่คุณได้รับศูนย์ที่คุณต้องการสตริงที่ว่างเปล่า คุณยังคงทำการดีบักบั๊กชนิดไม่ตรงกัน ข้อแตกต่างที่แท้จริงคือคอมไพเลอร์ไม่ได้จับข้อผิดพลาด

  • ฉันยืนยันว่าคุณไม่ได้ประหยัดการพิมพ์มากนัก - เพราะคุณมักจะต้องการเอกสารในความคิดเห็นว่าพารามิเตอร์ฟังก์ชันของคุณประเภทใดแทนที่จะเป็นเอกสารในรหัสของคุณ นี่คือเหตุผลที่บล็อกความคิดเห็นสไตล์ doxygen ได้รับความนิยมมากขึ้นในทางปฏิบัติผ่านโค้ดที่พิมพ์แบบไดนามิกซึ่งในภาษาที่พิมพ์แบบคงที่คุณส่วนใหญ่จะเห็นเฉพาะสำหรับไลบรารี

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


10
ฉันจะต้องแข่งขันกับโปรแกรมเมอร์ผู้มีประสบการณ์ที่ไม่ได้ทำ / แนะนำบั๊กเหล่านั้น นักพัฒนาที่ดีที่อ่อนน้อมถ่อมตนและรับทราบถึงความเป็นไปได้ที่พวกเขาทำผิดพลาด (และนักพัฒนาที่มีประสบการณ์ไม่ได้เป็นเช่นนี้เสมอไป) มีโอกาสน้อยที่จะสร้างข้อบกพร่องเหล่านั้น
Jay Jay Jay

12
ไม่สามารถตกลงเพิ่มเติมกับ "ฉันขอยืนยันว่าคุณไม่ได้ประหยัดการพิมพ์มากนัก" คุณจบประเภทเอกสารในความคิดเห็นและตรวจสอบพวกเขาในการทดสอบของคุณซึ่งถ้าจำเป็นต้องมีการพิมพ์และการบำรุงรักษามากขึ้น (หลังจากทั้งหมดคุณต้องจำไว้ว่าต้องอัปเดตความคิดเห็นดังกล่าวเมื่อใดก็ตามที่ประเภทของคุณเปลี่ยนไป )
Severyn Kozak

เราใช้เวลามากขึ้นในการจัดทำเอกสารร้านค้าของ Python มากกว่าที่เราจะประหยัดได้มากกว่าภาษาที่พิมพ์แบบคงที่เช่น C # หรือ Java นอกจากนี้ยังเป็นที่น่าสังเกตว่าภาษารุ่นใหม่เช่น Go และ Rust ใช้การอนุมานประเภทดังนั้นคุณจึงพิมพ์ "x: = new (Object)" แทน "Object x = new Object ()"
weberc2

ฉันเห็นด้วยกับคุณเมื่อคุณพูดว่าภาษาไดนามิกรู้สึกดีขึ้น แต่ฉันไม่รู้ว่าทำไม คุณมีคำอธิบายสำหรับสิ่งนั้นหรือไม่?
Rodrigo Ruiz

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

123

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


37
+1! "ข้อผิดพลาดเชิงตรรกะมีแนวโน้มที่จะกลายเป็นประเภทรวบรวมเวลาไม่ตรงกับแทนที่จะเกิดข้อผิดพลาด runtime หรือผลลัพธ์ไร้สาระ": คำตอบที่ดีจริงๆ! เมื่อฉันใช้เวลามากขึ้นในการออกแบบประเภทของฉันแล้วรหัสจะเป็นไปตามธรรมชาติมากขึ้นและมักจะถูกต้องทันทีที่รวบรวม การออกแบบประเภทหมายถึงการเข้าใจโดเมนและการดำเนินงาน
Giorgio

78

คำเตือน: ฉันเป็นคนรักประเภท;)

คำถามของคุณเป็นเรื่องยากที่จะตอบ: อะไรคือผู้ที่ไม่ชอบการค้า ?

ฉันจะยกตัวอย่างแบบสุดขั้ว: Haskellมันถูกพิมพ์แบบคงที่ บางทีหนึ่งในภาษาที่พิมพ์ออกมารุนแรงที่สุดที่มีอยู่จริง

อย่างไรก็ตาม Haskell สนับสนุนการเขียนโปรแกรมทั่วไปในแง่ที่ว่าคุณเขียนวิธีการที่ทำงานกับชนิดใดก็ได้ที่สอดคล้องกับแนวคิดที่แน่นอน (หรืออินเทอร์เฟซ)

นอกจากนี้ Haskell ยังใช้การอนุมานประเภทเพื่อที่คุณจะได้ไม่ต้องประกาศชนิดของตัวแปรของคุณ พวกเขาจะถูกคำนวณแบบคงที่ในระหว่างการรวบรวมมากที่สุดเท่าที่ Python Interpreter จะคำนวณพวกเขาทำงานโปรแกรม

ฉันได้พบว่าคนส่วนใหญ่มีความคิดสร้างสรรค์เกี่ยวกับการพิมพ์แบบคงที่มีการบ่นเกี่ยวกับสิ่งอื่น (verbosity, ความเจ็บปวดจากการสลับประเภทหนึ่งในความโปรดปรานของคนอื่น) แต่ Haskell แสดงไม่มีปัญหาเหล่านั้นในขณะที่พิมพ์แบบคงที่ ...


ตัวอย่างของความกะทัดรัด:

-- type
factorial :: Integer -> Integer

-- using recursion
factorial 0 = 1
factorial n = n * factorial (n - 1)

นอกเหนือจากการสนับสนุนในตัวแล้วก็ยากที่จะรับคนรับใช้

ตัวอย่างการเขียนโปรแกรมทั่วไป:

> reverse "hell­o" -- Strings are list of Char in Haskell
=> "olleh"
> reverse [1, 2, 3, 4, 5]
=> [5,4,3,2,1]

ตัวอย่างการอนุมานประเภท:

> :t rever­se "hell­o"
:: [Char]

ซึ่งสามารถคำนวณได้ง่าย ๆ :

  • "hello"เป็นรายการของChar(แสดงเป็น[Char])
  • reverseใช้กับชนิด[A]ส่งคืนชนิด[A]

ลองใช้ในเบราว์เซอร์ของคุณ


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

7
ฉันไม่รู้จัก Haskell แต่ +1 สำหรับ "จริง ๆ แล้วก็บ่นเรื่องอื่น (ความฟุ้งซ่านความเจ็บปวดจากการสลับประเภทหนึ่งไปสู่อีกแบบหนึ่ง)"
Nicole

1
@Aidan: Haskell เป็นภาษาที่พัฒนา Haskell 98 เป็นการปรับปรุง Haskell 1.4; Haskell 2010 ได้รับการปรับปรุงให้ดีขึ้น ในขณะเดียวกันก็เป็นที่น่าสังเกตว่าในช่วงชีวิตส่วนใหญ่raison d'êtreของ Haskell จะช่วยสำรวจระบบการพิมพ์ คลาสชนิดพารามิเตอร์หลายตัวเป็นหนึ่งในตัวอย่างที่การประสบความสำเร็จในการอธิบายส่วนขยายระบบประเภทที่มีประโยชน์ (ในทางกลับกันการพึ่งพาฟังก์ชั่นกำลังมองหาสิ่งที่เป็นจุดจบ)
geekosaur

4
@Matthieu: WRT "บางทีหนึ่งในภาษาส่วนใหญ่พิมพ์มั่นที่มีอยู่ในความเป็นจริง" ฉันจะเห็น Haskell ของคุณและเพิ่มคุณAGDAและCoq (ฉันจะให้มันเป็นภาษาที่ใช้งานได้จริงที่มีประโยชน์มากที่สุด)
geekosaur

1
@ Matthieu: ผู้ช่วยพิสูจน์เป็นแอปพลิเคชันโดยตรงของการติดต่อ Curry-Howard ดังนั้นพวกเขาจึงเป็นภาษาโปรแกรมภาษาหัวใจ (แม้ว่าจะมีห้องสมุดมาตรฐานค่อนข้าง จำกัด ) พวกเขาอยู่ในระดับแนวหน้าของการวิจัยประเภทที่ต้องพึ่งพาเพราะคุณต้องการประเภทที่ขึ้นต่อกันเพื่อใช้ประโยชน์จากการโต้ตอบของ "ประเภทของข้อเสนอ"
geekosaur

37

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

1) คุณมักจะสามารถอนุมานได้ว่าฟังก์ชั่นนั้นทำอะไรจากลายเซ็นประเภทของมัน (นี่เป็นเรื่องจริงในภาษาที่ใช้งานได้เช่น Haskell)

2) เมื่อคุณทำการ refactor ที่สำคัญคอมไพเลอร์จะบอกคุณทุกอย่างที่คุณต้องทำเพื่อให้ทุกอย่างทำงานได้โดยอัตโนมัติ เมื่อฉัน refactor บางอย่างใน C ++ โพรซีเดอร์ของฉันมักจะเป็นเพียงแค่ a) เปลี่ยนส่วนที่ฉันรู้ว่าฉันต้องการเปลี่ยนจากนั้น b) แก้ไขข้อผิดพลาดคอมไพล์ทุกข้อ


เหมือนกันกับฉันและเมื่อใดก็ตามที่ฉันต้องการ refactor บางสิ่งบางอย่าง (ส่วนใหญ่ฉันใช้ golang / typescript / java) ใช่ 2 ขั้นตอนเหล่านั้นเป็นสิ่งที่ทุกคนต้องการ เปลี่ยนส่วนหนึ่งแล้วแก้ไขข้อผิดพลาดการรวบรวมทั้งหมด :) คำตอบที่สมบูรณ์แบบ
Nishchal Gautam

29

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

ที่สำคัญที่สุดสำหรับฉันคือแม้ว่าฉันจะสูญเสียความยืดหยุ่นบางอย่าง แต่ฉันก็มีเวลาที่จะต้องติดตามปัญหาประเภทอื่น ๆ


13

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

ใช่พิมพ์คงมีมูลค่าการค้าไม่ชอบ - และไม่เพียงแค่เล็กน้อย แต่ในความเป็นจริงอย่างมาก ในความเป็นจริงหลักฐานที่มั่นคงแสดงให้เห็นว่าการพิมพ์แบบคงที่สามารถลดจำนวนข้อบกพร่องในรหัสได้อย่างน้อย 15% (และนี่เป็นการประมาณการที่ต่ำ นั่นเป็นจำนวนที่สูงอย่างน่าตกใจ : ฉันคิดว่าแม้ผู้เสนอแบบคงที่ส่วนใหญ่คงไม่คิดว่ามันสร้างความแตกต่างอย่างมาก

ลองพิจารณาสิ่งนี้: ถ้ามีคนบอกคุณว่ามีวิธีง่ายๆในการลดข้อบกพร่องในโครงการของคุณ 15% ในชั่วข้ามคืนนั่นควรจะเป็นเรื่องที่ไม่ต้องคิดอะไร 1 เกือบจะเป็นกระสุนเงินสุภาษิต

มีการนำเสนอหลักฐานในกระดาษเพื่อพิมพ์หรือไม่พิมพ์: การตรวจหาปริมาณแมลงที่ตรวจพบได้ในจาวาสคริปต์โดย Zheng Gao, Christian Bird และ Earl T. Barr ฉันขอแนะนำให้ทุกคนอ่านมันเป็นบทความที่ดีที่นำเสนองานวิจัยที่เป็นแบบอย่าง

เป็นการยากที่จะสรุปรวบยอดว่าผู้เขียนทำการวิเคราะห์อย่างจริงจังเพียงใด แต่นี่เป็นโครงร่างที่หยาบ (หยาบมาก):

TypeScriptและFlowเป็นภาษาการเขียนโปรแกรมสองภาษาโดยยึดตามจาวาสคริปต์ซึ่งในขณะที่ยังคงใช้งานร่วมกันได้ให้เพิ่มการระบุประเภทและการตรวจสอบประเภทสแตติก ซึ่งอนุญาตให้เพิ่มรหัสที่มีอยู่ตามประเภทและจากนั้นให้พิมพ์ตรวจสอบ

นักวิจัยได้รวบรวมโครงการโอเพ่นซอร์สที่เขียนด้วย JavaScript จาก GitHub ดูรายงานข้อผิดพลาดที่ได้รับการแก้ไขและพยายามที่จะลดข้อผิดพลาดที่รายงานแต่ละรายการให้เป็นชิ้นส่วนของรหัสที่จะถูกตรวจจับโดยตัวตรวจสอบชนิดคงที่ของ สิ่งนี้ทำให้พวกเขาประมาณขอบเขตล่างของเปอร์เซ็นต์ของบั๊กสามารถแก้ไขได้โดยใช้การพิมพ์แบบสแตติก

นักวิจัยใช้ความระมัดระวังอย่างเข้มงวดเพื่อให้แน่ใจว่าการวิเคราะห์ของพวกเขาจะไม่พิจารณาข้อผิดพลาดที่เกี่ยวข้องกับประเภทที่ไม่เกี่ยวข้องกับประเภท 2

เปรียบเทียบกับการศึกษาที่ผ่านมาการศึกษาใหม่นี้มีจุดแข็งเฉพาะ:

  • มีการเปรียบเทียบโดยตรงของการพิมพ์แบบสแตติกvsไดนามิกโดยมีปัจจัยรบกวนน้อย (ถ้ามี) เนื่องจากความแตกต่างเพียงอย่างเดียวระหว่าง JavaScript และ TypeScript / Flow คือการพิมพ์
  • พวกเขาทำการจำลองแบบข้ามมิติต่าง ๆ โดยการตรวจสอบทั้ง TypeScript และ Flow (เช่นระบบประเภทที่แตกต่างกัน) และโดยให้คนอื่นสร้างคำอธิบายประกอบประเภท (ด้วยตนเอง) เพื่อแก้ไขข้อบกพร่อง และพวกเขาทำสิ่งนี้กับฐานรหัสจำนวนมากจากโครงการที่แตกต่างกัน
  • กระดาษวัดผลกระทบโดยตรงจากการพิมพ์แบบคงที่ในข้อบกพร่องที่แก้ไขได้ (มากกว่าคุณภาพที่คลุมเครือมากขึ้น)
  • ผู้เขียนกำหนดรูปแบบที่เข้มงวดของสิ่งที่จะวัดและวิธีการล่วงหน้า นอกจากนี้คำอธิบายของพวกเขายังชัดเจนอย่างไม่น่าเชื่อและทำให้ง่ายต่อการวิเคราะห์ข้อบกพร่อง (ดีเสมอเมื่อรายงานการวิจัยเปิดตัวขึ้นมาเพื่อโจมตี: หากไม่มีการโจมตีใดที่จัดการกับข้อโต้แย้ง 3
  • พวกเขาทำการวิเคราะห์พลังงานที่เหมาะสมเพื่อให้ขนาดตัวอย่างของพวกเขาเพียงพอและการวิเคราะห์ทางสถิติที่ตามมาของพวกเขาคือสุญญากาศ
  • พวกมันมีความอนุรักษ์นิยมมากเกินไปที่จะไม่รวมคำอธิบายที่สับสนและวัดได้เพียงส่วนเดียวที่เคลื่อนไหว นอกจากนี้พวกเขายัง จำกัด การวิเคราะห์ข้อบกพร่องที่สามารถแก้ไขได้ทันทีโดยรวมถึงประเภทและแยกสิ่งที่อาจต้องมีการปรับโครงสร้างขั้นสูงเพิ่มเติมเพื่อรองรับการพิมพ์ ดังนั้นในความเป็นจริงเอฟเฟกต์น่าจะใหญ่กว่ามาก แต่แน่นอนไม่น้อยไปกว่าที่พวกเขารายงาน
  • และในที่สุดพวกเขาไม่พบผลกระทบเล็กน้อย แต่มีความแตกต่างที่น่าทึ่ง แม้จะมีขั้นตอนที่อนุรักษ์นิยมมากเกินไปแม้ในช่วงท้ายสุดของช่วงความมั่นใจ 95% พวกเขาพบว่ามีข้อผิดพลาดอย่างน้อย 10% ที่จะหายไปเมื่อมีการตรวจสอบประเภทเพิ่มน้อยที่สุด

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


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

จริงๆแล้วมีภาษาโปรแกรมที่อนุญาตให้พิมพ์ทั้งแบบคงที่และแบบไดนามิกในภาษาที่แตกต่างกัน (เช่น VB กับOption Strict OnหรือOffหรือพิมพ์ Lisp แบบคงที่) อย่างไรก็ตามสิ่งเหล่านี้ไม่เหมาะสำหรับการเปรียบเทียบโดยตรงสิ่งสำคัญที่สุดเนื่องจากไม่มีฐานรหัสขนาดใหญ่ที่มีอยู่เพียงพอที่สามารถทำการเปรียบเทียบโดยตรงได้ ที่ดีที่สุดเราสามารถเปรียบเทียบพวกเขาใน "การตั้งค่าห้องปฏิบัติการ" โดยที่ผู้ทดสอบจะทำการสุ่มแก้ปัญหาในภาษาที่แปรผันแบบคงที่หรือแบบไดนามิก

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

โชคดีที่ในอดีตนั้นเป็นเพราะ TypeScript, Flow และ JavaScript เป็นภาษาเดียวกันยกเว้นการพิมพ์แบบสแตติกและเนื่องจากมีชุดข้อมูลรหัสและข้อบกพร่องมากมายในโลกแห่งความเป็นจริง


1แรงบันดาลใจจากคำพูดจากกระดาษต้นฉบับ

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

3ฉันขอเชิญชวนทุกคนโดยเฉพาะอย่างยิ่งผู้สนับสนุนของการพิมพ์แบบไดนามิกเพื่อพยายามหาข้อบกพร่องที่ไม่ได้รับการแก้ไขในการวิเคราะห์ ฉันไม่คิดว่ามีจำนวนมาก (ถ้ามี) และฉันมั่นใจว่าไม่มีข้อบกพร่องที่เป็นไปได้ที่จะเปลี่ยนแปลงผลลัพธ์อย่างมีนัยสำคัญ

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


3
ฉันรู้ว่านี่เป็นคำตอบที่ช้าสำหรับคำถามนี้ แต่ฉันเชื่อว่าหลักฐานใหม่ (ซึ่งฉันอธิบายที่นี่) เปลี่ยนการอภิปรายแบบสแตติก - vs - ไดนามิกที่สมบูรณ์
Konrad Rudolph

2
มันน่าสนใจอย่างแน่นอน แต่ฉันสงสัยว่าเกี่ยวข้องกับระบบเฉพาะของจาวาสคริปต์มากแค่ไหน ระบบประเภทของ Python (โดยเฉพาะ python3) นั้นเข้มงวดกว่าและมีการแปลงโดยนัยน้อยกว่ามาก
Peter Green

@PeterGreen ใช่นั่นเป็นเรื่องจริงไม่ต้องสงสัย บางทีเราอาจโชคดีและคำใบ้ของไพ ธ อนจะนำไปสู่การวิเคราะห์ที่คล้ายกัน (แม้ว่าฉันจะสงสัยก็ตามเนื่องจากวัตถุประสงค์ที่แสดงไว้ใน PEP484 & PEP526 นั้นไม่ได้ใช้การพิมพ์คงที่)
Konrad Rudolph

1
เพียงแค่อ่านบทคัดย่อที่ฉันสามารถบอกได้ว่าวิธีการมีข้อบกพร่องพื้นฐาน คุณไม่สามารถใช้ codebase ที่เขียนโดยใช้ระเบียบวินัยเดียวแล้วเพิ่มประเภทเพื่อแสดงเหตุผลในข้อแตกต่างกันโดยสิ้นเชิง รหัสที่เขียนเป็นระเบียบวินัยแบบสแตติกนั้นแตกต่างจากระเบียบวินัยแบบไดนามิกโดยทั่วไปคุณไม่ควรเขียน Java ใน Python เหมือนกับที่คุณไม่ควรเขียน Python ใน Java แม้แต่ typescript และ javascript ก็เป็นภาษาที่แตกต่างกันโดยพื้นฐานแม้จะมีความคล้ายคลึงกันเพียงผิวเผินก็ตาม
Lie Ryan

2
@LieRyan หากมีสิ่งใดที่ทำให้การวิเคราะห์แบบอนุรักษ์นิยมมากเกินไปดังที่ระบุไว้ในคำอธิบายของฉันและที่อื่น ๆ มันไม่ได้ทำให้การวิเคราะห์เป็นโมฆะ ค่าประมาณ 1% ของคุณคืออย่างซื่อสัตย์และน่าหัวเราะ มันปิดสนิทสัญชาตญาณของคุณกำลังทำให้คุณผิดหวัง ในทำนองเดียวกันลักษณะของปัญหาการพิมพ์แบบคงที่เป็นเรื่องปกติของผู้ปฏิบัติงานของการพิมพ์แบบไดนามิกที่มีประสบการณ์จริงเล็กน้อยกับการพิมพ์แบบคงที่ที่ทันสมัย ​​(เช่นไม่ใช่จาวา)
Konrad Rudolph

12

ความปลอดภัยของประเภทคุ้มค่าต่อการพัฒนาและความยืดหยุ่นหรือไม่?

ดังนั้นนี่คือสิ่งที่คุณกำลังทำอยู่ หากคุณกำลังเขียนโปรแกรมพูดว่าระบบสำรองข้อมูลสำหรับเครื่องบินความปลอดภัยประเภทน่าจะเป็นวิธีที่จะไป

Dynamic language vs การเขียนโปรแกรมภาษาคงเป็นสัตว์สองชนิดที่แตกต่างกันจริงๆ พวกเขาทั้งสองต้องการวิธีการที่แตกต่างกันโดยพื้นฐานจากกันและกัน คุณสามารถพอร์ตวิธีการระหว่างสถิตและไดนามิกส่วนใหญ่ แต่คุณจะสูญเสียข้อดีของอีก

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

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


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

7

มีคำถามที่คล้ายกันที่เพิ่งถามเมื่อเร็ว ๆ นี้คือ: ภาษาที่มีการพิมพ์แบบไดนามิกและแบบคงที่สำหรับเว็บไซต์

ในการย้ำหลักของคำตอบของฉัน:

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

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

โดยส่วนตัวแล้วฉันทำการพัฒนาส่วนใหญ่ในhaXeซึ่งมีระบบแบบสแตติก ไม่เพียง แต่มันจะแสดงออกอย่างชัดเจนมากขึ้นกว่าของ Java และมันต้องใช้ความพยายามน้อยลงมากเนื่องจากการอนุมานประเภท แต่ยังเป็นตัวเลือก หากมันได้รับในทางของคุณคุณเพียงแค่ข้ามมัน

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

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

ตัวอย่างรหัส haXe:

class Car {
    public function new();
    public function wroom() trace('wroooooooom!')
}
class Duck {
    public function new();
    public function quack(at) trace('quackquack, ' + at + '!')
}

function letQuack(o) o.quack();
letQuack(new Car());
letQuack(new Duck());

สิ่งนี้จะทำให้เกิดข้อผิดพลาดในการรวบรวมเวลา:

Car should be { quack : Void -> Unknown<0> }
Car has no field quack
For function argument 'o'
Duck should be { quack : Void -> Unknown<0> }
Invalid type for field quack :
to : String -> Void should be Void -> Unknown<0>
For function argument 'o'

คุณไม่สามารถอ้างสิทธิ์ได้ว่าฉันต้องใช้ความพยายามอย่างมากกับความปลอดภัยของประเภท

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

ในตอนท้ายของวันคุณจะพบว่าไม่ว่าคุณจะเสียค่าใช้จ่ายในเรื่องความปลอดภัยมากแค่ไหนก็ตามในที่สุดมันก็จะถูกทำลาย (แม้ใน Java - แม้ว่าอาจจะไม่ช้าก็ตาม)


ในชุดคำสั่ง python จะถูกคัดลอกและวางจาก repl / shell เพื่อเป็นแหล่งของเอกสารและการตรวจสอบในภายหลัง docs.python.org/3/library/doctest.html
aoeu256

5

ไม่ว่าด้วยเหตุผลใดฉันจะไม่ทำผิดเกี่ยวกับประเภทของวัตถุที่มักจะเกิดขึ้นอีก ในภาษาเช่น C # ฉันมักจะทำผิดพลาดที่เกี่ยวข้องกับ runtime ปลดเปลื้องมากกว่าฉันน่าจะทำให้เกิดข้อผิดพลาดด้านความปลอดภัยที่ตรวจพบคอมไพเลอร์ชนิดซึ่งฉันให้มักจะเกิดจากความต้องการเป็นครั้งคราวเพื่อหลีกเลี่ยงความนิ่ง ภาษาที่พิมพ์ เมื่อฉันเขียน ruby ​​รหัสมีแนวโน้มที่จะบอกใบ้เกี่ยวกับประเภทของวัตถุและความพร้อมใช้งานของ REPL นั้นหมายความว่าฉันได้ทำการทดสอบแล้วว่ามีวิธีการ / คุณสมบัติที่ต้องการหรือฉันจะทำการทดสอบหน่วยที่ทำ โดยพื้นฐานแล้วเป็นสิ่งเดียวกันดังนั้นฉันจึงไม่ค่อยพบปัญหาด้านความปลอดภัยในประเภททับทิม

แต่นั่นก็ไม่ได้หมายความว่าระบบที่พิมพ์แบบสแตติกไม่สามารถทำได้ดีกว่าระบบ

ในภาษาที่พิมพ์แบบสแตติกระบบพิมพ์ก็มีความสำคัญเช่นกัน ตัวอย่างเช่นบางอย่างในบางภาษาในภาษาที่ใช้งานได้ (พิมพ์ <Some>: = ใช่ x | ไม่) คุณจะได้รับการตรวจสอบเวลาคอมไพล์ที่ป้องกันไม่ให้ NullReferenceException ที่หวั่นกลัวในระบบประเภทส่วนใหญ่ เมื่อรหัสการจับคู่รูปแบบทำงานคุณจะได้รับข้อผิดพลาดในการรวบรวมเวลาซึ่งบอกคุณว่าคุณไม่สามารถจัดการกับเงื่อนไขที่เป็นโมฆะได้ (หากคุณใช้กลไกนั้นในการประกาศประเภท) คุณยังลดข้อผิดพลาดประเภทที่คล้ายกันเมื่อคุณใช้สิ่งต่าง ๆ เช่น |> ตัวดำเนินการไปป์ไลน์ใน F #

ในประเพณีของ Hindley – Milner ของการพิมพ์แบบสแตติกคุณสามารถสร้างสิ่งต่าง ๆ ที่ให้คุณมากกว่าการรับประกันว่าประเภทที่อ้างว่าสนับสนุนอินเตอร์เฟส X และเมื่อคุณมีสิ่งเหล่านั้นฉันจะบอกว่าระบบที่พิมพ์แบบคงที่จะกลายเป็นจำนวนมาก มีคุณค่ามากขึ้น

เมื่อไม่มีตัวเลือกส่วนขยาย Design By Contract ไปยัง C # สามารถเพิ่มชุดของกลไกอื่นที่เพิ่มมูลค่าของระบบชนิดสแตติก แต่ยังคงต้องมีระเบียบวินัยมากกว่ากระบวนทัศน์การทำงานบางอย่าง


5

มันขึ้นอยู่กับ.

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

การลดอัตราความล้มเหลวที่อาจเกิดขึ้นนี้มีค่าหรือไม่ขึ้นอยู่กับว่า

หากคุณกำลังเขียนรหัสสำหรับโรงไฟฟ้านิวเคลียร์หรือระบบ ATC การลดโหมดความล้มเหลวของมนุษย์อาจมีความสำคัญอย่างยิ่ง หากคุณกำลังสร้างต้นแบบอย่างรวดเร็วความคิดบางอย่างของเว็บไซต์ที่ไม่มีข้อมูลจำเพาะและมีผลลัพธ์ใกล้เคียงกับความล้มเหลวเป็นศูนย์การลดโหมดความล้มเหลวหรือความน่าจะเป็นอาจจะหรืออาจจะไม่ซื้ออะไรก็ได้ แต่อาจทำให้คุณเสียเวลาในการพัฒนา และในเซลล์สมองเบี่ยงเบนความสนใจจากการจำประเภทปัจจุบันที่จำเป็น


3
สถานการณ์สมมติของคุณเกี่ยวกับการสร้างต้นแบบอย่างรวดเร็วนั้นเป็นเรื่องที่ผิดในบทความของ Paul Hudak เกี่ยวกับการศึกษากองทัพเรือสหรัฐฯซึ่งจำเป็นต้องพัฒนาแบบจำลองคล้าย AEGIS ในภาษาต่างๆซึ่งหนึ่งในนั้นคือ Haskell มันตรงตามเกณฑ์เกือบทั้งหมดของคุณ: เป็นการสร้างต้นแบบอย่างรวดเร็วข้อกำหนดที่กำหนดไว้ไม่ดีและค่าใช้จ่ายของความล้มเหลวอยู่ใกล้ศูนย์ (นี่เป็นการทดลองที่ไม่เป็นทางการ) Haskell ออกมาเป็นผู้ชนะในหมวด evey: เวลาในการพัฒนา, เกินข้อกำหนด, ใช้ LOC น้อยกว่าและสร้างตัวอย่างการทำงานเพียงหนึ่งเดียวในบรรดาผู้แข่งขันทั้งหมด!
Andres F.

2
กระดาษ: Haskell VS ... , การทดลองในซอฟแวร์การสร้างต้นแบบผลผลิต - พอลฮูดักและมาร์คโจนส์พี มันอธิบายถึงผลการทดลองที่ ARPA และกองทัพเรือสหรัฐฯสั่ง
Andres F.

ผู้ชนะ Relational Lisp ไม่ใช่หรือ ผู้ชายฉันหวังว่าจะมี vids ที่แสดงให้ผู้คนเขียนสิ่งต่าง ๆ ใน LISP กับส่วนขยายที่ทรงพลังแปลก ๆ เช่น Shen (กรอบการทำงานเชิงตรรกะเชิงตรรกะที่อนุญาตให้คุณให้ประเภทที่ขึ้นกับรหัสและรหัสประเภทผสมและจับคู่กับรหัสที่ไม่ใช่ประเภท ), เฟรม Super-CLOS พร้อม
เพรดิเคตดิสทริบิวต์

4

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

ยิ่งกว่านั้นภาษาที่พิมพ์แบบสแตติกแบบกระแสหลักดูเหมือนจะไม่เหมาะสำหรับการตรวจจับข้อผิดพลาด ในการออกแบบรูปแบบเป็นสิ่งที่สำคัญคือจำนวนหนึ่งคือการวัดแนวตั้งบนหน้าไม่ว่าจะเป็นint, unsigned, หรือfloat doubleในทางกลับกันคอมไพเลอร์มักจะแปลงประเภทการตั้งค่าสถานะว่ามันไม่ปลอดภัยและให้ฉันเพิ่มการวัดในแนวตั้งและจำนวนตัวอักษรในสตริงอย่างมีความสุข จุดอ่อนของระบบแบบสแตติกนี้เป็นแนวคิดดั้งเดิมที่อยู่เบื้องหลังสัญกรณ์ฮังการีของ Simonyi ก่อนที่มันจะถูกทำให้ไร้ประโยชน์จนน่าเกลียด


4

ประเภทเป็นข้อ จำกัด ในอินเทอร์เฟซดังนั้นพวกมันจึงเป็นส่วนย่อยของสิ่งที่คุณอาจต้องการทดสอบด้วยการทดสอบหน่วยและข้อเสียมากมายมีความคล้ายคลึงกัน:

  • ประเภทคงที่ให้ข้อเสนอแนะก่อนหน้านี้หรือไม่ว่ารหัสตรงตามข้อกำหนดที่สามารถแสดงโดยระบบประเภทในการแลกเปลี่ยนสำหรับความล่าช้าในการตอบรับจากการสร้างสิ่งที่ทำงานได้น้อยที่สุด (เช่นความคิดเห็นของลูกค้าหรือการทดสอบระดับที่สูงขึ้น)
  • การรู้ว่ารหัสตรงตามข้อกำหนดบางประการสามารถทำให้การปรับโครงสร้างและการดีบักง่ายขึ้น แต่ยังเพิ่มค่าใช้จ่ายในการเปลี่ยนอินเตอร์เฟสและข้อกำหนดการเปลี่ยนแปลง
  • โดยเฉพาะอย่างยิ่งถ้าภาษาที่พิมพ์แบบสแตติกขาดการบีบบังคับมันจะเพิ่มความปลอดภัยต่อโค้ดที่ใช้กับข้อมูลที่จะทำให้เกิดข้อบกพร่อง (ลดความต้องการเงื่อนไขและการยืนยัน) แต่ข้อ จำกัด ที่ จำกัด มากเกินไปทำให้ผู้ใช้ต้องเขียนโค้ดเพิ่มเติมเพื่อนวดข้อมูล แบบฟอร์มที่ยอมรับได้ (เช่นการส่งแบบชัดเจน)
  • คำอธิบายประกอบประเภทที่ชัดเจนสามารถช่วยในการทำความเข้าใจเมื่ออ่านรหัสหรือสามารถถ่วงรหัสด้วยข้อมูลซ้ำซ้อนหรือข้อมูลที่ไม่จำเป็น
  • ขึ้นอยู่กับการนำไปใช้งานมันสามารถเบี่ยงเบนความตึงเครียดได้ สิ่งนี้ขึ้นอยู่กับสิ่งต่าง ๆ เช่นต้องการให้คำอธิบายประกอบประเภทหรืออนุมานว่าระบบประเภทสามารถแสดงประเภท / อินเตอร์เฟสทั่วไปไวยากรณ์ได้ดีเพียงใดและคุณตั้งใจจะทดสอบข้อ จำกัด ที่สามารถแสดงออกได้ด้วยระบบประเภทนั้นหรือไม่ การทดสอบเดียวกันนั้นมีความหมายสั้นกว่าในลักษณะของภาษามากกว่าการทดสอบหน่วย แต่คุณอาจไม่ได้ตั้งใจทดสอบ)
  • นอกจากนี้ (แต่ไม่เกี่ยวข้องกับ TDD) ประเภทสแตติกสามารถช่วยในการปรับเวลาให้เหมาะสมโดยใช้ค่าใช้จ่ายในการตรวจสอบประเภทนั้น (และใช้เวลาในการตรวจสอบและทำการปรับให้เหมาะสม) และการปรับให้เหมาะสมที่ดีกว่า แมปนั้นกับฮาร์ดแวร์ สิ่งนี้จะช่วยลดการพัฒนาโค้ดที่มีข้อกำหนดด้านประสิทธิภาพ แต่อาจทำให้เกิดปัญหากับโค้ดที่ไม่สอดคล้องกับข้อ จำกัด เหล่านี้ได้ดี (ตามจุด 3)

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


3

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


4
ภาษาที่มีการพิมพ์อย่างมากเช่น Java และ C # จัดการการดีซีเรียลไลเซชันโดยอัตโนมัติผ่านการใช้ Reflection
Matthieu M.

3

มอร์แกนฉันมีความคิดที่น่าสนใจสำหรับคุณที่จะลอง: การพิมพ์สแตติก + แบบไดนามิก คุณพูดถึง Python, C # และ Java คุณทราบหรือไม่ว่ามีบางพอร์ตที่ดีของ Python สำหรับทั้ง. NET และ Java ในทั้งสองกรณีพอร์ตต่างๆให้คุณใช้ไลบรารีของแพลตฟอร์มเหล่านั้นและ / หรือทำงานร่วมกับโค้ดที่มีอยู่ สิ่งนี้ทำให้คุณมีความเป็นไปได้หลายอย่าง:

  1. เก็บรหัสดั้งเดิมในภาษาแบบคงที่และไม่ยืดหยุ่น ใช้ Python สำหรับสิ่งใหม่ ๆ
  2. ใช้ Python เพื่อสร้างต้นแบบสิ่งใหม่ ๆ บนแพลตฟอร์มที่สมบูรณ์ เขียนโค้ดส่วนประกอบที่คุณต้องการเก็บไว้ในภาษาที่เป็นผู้ใหญ่มากขึ้น
  3. ใช้ภาษาไดนามิกสำหรับบางส่วนที่คุณเปลี่ยนบ่อย
  4. อาจใช้ภาษาไดนามิกในการเล่นกับแนวคิดต่างๆเช่นการแก้ไขโค้ดที่ใช้งาน
  5. ทำทุกสิ่งในภาษาไดนามิกยกเว้นส่วนที่สำคัญซึ่งคุณใช้ภาษาที่พิมพ์อย่างรุนแรง

ฉันใช้วิธีการเหล่านี้ย้อนกลับไปจนถึงช่วงปลายยุค 90 เพื่อแก้ไขความเจ็บปวดในการพัฒนาใน C / C ++ ฉันต้องการห้องสมุดท้องถิ่นและบางครั้งประสิทธิภาพ แต่ฉันต้องการไวยากรณ์ที่ดีกว่าความยืดหยุ่นความปลอดภัย ฯลฯ ดังนั้นเคล็ดลับคือการรวมพวกเขาอย่างระมัดระวังเพื่อให้ได้การแลกเปลี่ยนที่ถูกต้อง ในทางปฏิบัติมักจะดีกว่าการทิ้งทั้งภาษาและรหัสดั้งเดิมสำหรับภาษา / แพลตฟอร์มอื่น

(หมายเหตุ: คำตอบได้ตอบไปแล้ว แต่ฉันต้องการเน้นย้ำอีกครั้งว่าการพิมพ์แบบไดนามิก! = ไม่ / การพิมพ์ที่อ่อนแอระบบพิมพ์แบบไดนามิกจำนวนมากใช้การพิมพ์ที่แข็งแกร่งด้านในวิธีที่ฉันคิดเกี่ยวกับสิ่งที่ทำให้การเปลี่ยนแปลงแบบคือ ประเภทของตัวแปรถูกกำหนดที่รันไทม์ไม่จำเป็นต้องมีคำอธิบายประกอบประเภทและ / หรืออาจเปลี่ยนแปลงได้ที่รันไทม์


2

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


นี่เป็น QA แบบอัตนัยดังนั้นฉันสบายดี
Morgan Herlocker

1
ใครสนใจอธิบายการลงคะแนนเสียง?
pdr

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

5
ฉันไม่ได้ลงคะแนนในขณะที่คุณทำจุดที่ถูกต้องแม้ว่าจะไม่ได้มีการกระทำความผิด แต่โพสต์ของคุณพบว่าเป็นแฟนพันธุ์แท้ TDD เล็ก ๆ น้อย ๆ ซึ่งอาจเป็นเหตุผลที่ผู้ลงคะแนน
Karl Bielefeldt

@Karl ไม่มีความผิดมันเป็นคำถามของแท้ ฉันสามารถเป็นอาภรณ์แห่ง TDD ได้โดยอัตโนมัติฉันยอมรับ
pdr

2

ฉันเห็นคำถามนี้เกิดขึ้นมากมายและฉันคิดว่าคุณภาพซอฟต์แวร์ของคุณ (และการไม่มีข้อบกพร่อง) มีมากขึ้นเกี่ยวกับกระบวนการพัฒนาของคุณวิธีที่ระบบของคุณได้รับการออกแบบและความมุ่งมั่นของคุณและเพื่อนร่วมงานของคุณต่อคุณภาพของรหัส

งานสุดท้ายของฉันคือการพัฒนาหลามส่วนใหญ่ ฉันทำงานให้กับ บริษัท โฮสติ้งเว็บระหว่างประเทศขนาดใหญ่และเรามีทีมงานพัฒนาในสหรัฐอเมริกาแคนาดาและเกาหลีใต้ โครงร่างเว็บหลามแบบกำหนดเองสำหรับแอปลูกค้าปลายด้านหน้าที่อนุญาตให้ผู้ใช้จัดการชื่อโดเมนและบัญชีเว็บโฮสติ้งของพวกเขา แบ็กเอนด์: หลามทั้งหมดเช่นกัน บริการเว็บไพ ธ อนเพื่อพูดคุยกับเซิร์ฟเวอร์แต่ละตัวเพื่อทำสิ่งต่าง ๆ เช่นจัดเตรียมเว็บไซต์ใหม่สำหรับโฮสต์เว็บสร้างบล็อกใหม่สร้างรายการ DNS ในระบบบริการชื่อของเรา ฯลฯ ในงานปัจจุบันของฉันลูกค้าแอปทั้งหมดของเราใน java; ผลิตภัณฑ์หลักของเราคือส่วนผสมของจาวาและแฟลช กรอบเว็บ Java ที่กำหนดเองสำหรับแอปรุ่นเก่าของเราประตูสำหรับเครื่องมือภายในใหม่ของเรา

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


2

ความปลอดภัยของประเภทคุ้มค่าต่อการพัฒนาและความยืดหยุ่นหรือไม่? ทำไม?

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

จะมีอาการปวดหัวในการพัฒนาซอฟต์แวร์อยู่เสมอเนื่องจาก:

  • ความซับซ้อนโดยธรรมชาติของสิ่งที่คุณพยายามทำให้สำเร็จ

  • ความผิดพลาดโดยธรรมชาติของมนุษย์โดยเฉพาะอย่างยิ่งการพิจารณาว่าเราทำผิดพลาดมากขึ้นเมื่อเราพยายามทำสิ่งที่ซับซ้อนมากขึ้น

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

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


1

นี่เป็นเพียงความเห็นของฉันเอง แต่ไม่ฉันไม่คิดว่าความปลอดภัยประเภทนั้นคุ้มค่า ไม่แม้แต่วินาทีเดียว

ฉันเป็นนักพัฒนามานาน เริ่มต้นด้วย c ++, c # จากนั้นย้ายไปที่ javascript (ส่วนหน้าและส่วนหลังผ่าน node.js) ตั้งแต่ฉันพัฒนาจาวาสคริปต์ผลผลิตของฉันเพิ่มขึ้นอย่างรวดเร็วจนถึงจุดที่ทำให้ฉันรู้สึกแย่โดยใช้ภาษาที่ใช้พิมพ์ ฉันยังต่อต้านการคอมไพล์ฉันต้องการให้ทุกอย่างเรียบร้อยในขณะนี้ ภาษาที่ตีความเป็นจริงที่ฉันพบว่าฉันรักการเขียนโปรแกรม

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

นี่คือตัวอย่าง ฉันเพิ่งใช้ Swift (ภาษาใหม่ของ Apple) หวังว่ามันจะมีชีวิตจริงตามชื่อของมันเมื่อวันก่อนและพยายามทำ: var n = 1/2 ไม่ทำงาน ฉันชอบสิ่งที่เกิดขึ้นที่นี่ และจากนั้นก็รู้ว่าเศร้าฉันต้องทำ var n: Float = 1/2 สิ่งนี้เตือนฉันว่าฉันเกลียดระบบพิมพ์มากแค่ไหน

ฉันยังต้องไปอีกหนึ่งไมล์เพื่อบอกว่าฉันไม่ต้องการแม้แต่ประเภทที่ผู้ใช้กำหนดเอง (เช่นคลาส) ฉันไม่ต้องการประเภทเลย ทั้งหมดที่ฉันต้องการคือ var และวัตถุ สามารถใช้วัตถุใดก็ได้เป็นวัตถุใดก็ได้ และวัตถุนั้นมีพลวัตและเปลี่ยนแปลงอยู่ตลอดเวลา มันจะกลายเป็นปัญหารันไทม์ที่สิ่งที่ใช้งานได้และสิ่งที่ไม่

นักพัฒนาชอบที่จะพูดว่าภาษาที่พิมพ์อย่างหลวม ๆ ไม่ดีสำหรับโครงการขนาดใหญ่ แต่ฉันจะบอกว่ามันตรงกันข้าม ภาษาที่พิมพ์ได้ดีมีความน่ากลัวสำหรับโครงการขนาดใหญ่ และถ้าคุณบอกว่าจาวาสคริปต์ใช้งานไม่ได้กับโครงการขนาดใหญ่ให้ถาม บริษัท Uber ที่มีมูลค่า 40 พันล้าน + ที่ให้แบ็กเอนด์ทั้งหมดบน node.js / javascript หรือ Facebook ที่เริ่มต้นด้วย PHP

เท่าที่ภาษาที่พิมพ์แบบคงที่จะไม่ดีสำหรับการทำซ้ำอย่างรวดเร็วของวันนี้ นี่คือตัวอย่างง่ายๆคุณมี 10 นักพัฒนาที่ทำงานในโครงการ. net พร้อมเซิร์ฟเวอร์การรวมอย่างต่อเนื่องผู้พัฒนารายหนึ่งส่งข้อผิดพลาดและบิลด์ทั้งหมดเสียแม้ว่าผู้พัฒนา 10 คนกำลังทำงานในสิ่งต่าง ๆ ที่พวกเขาหยุดและรออยู่ สำหรับผู้พัฒนาที่กระทำผิดเพื่อแก้ไขข้อผิดพลาดของเขา พูดคุยเรื่องประสิทธิภาพแล้วเหรอ? พิมพ์ระบบ / ภาษาคงมีการพึ่งพาซึ่งกันและกันในวิธีการนั้นและทำให้การพึ่งพารหัสของคุณ อย่างไรก็ตามไฟล์สคริปต์จะไม่พึ่งพาซึ่งกันและกัน หากมีปัญหากับสคริปต์ตัวใดตัวหนึ่งที่ไม่ได้หยุดการผลิตปัญหาทั้งหมดที่คุณเห็นจะอยู่ในรันไทม์ และรันไทม์ไม่เคยหยุด มันไม่เคยหยุดพัก มันอาจสร้างผลลัพธ์ที่ผิด แต่มันก็ไม่ได้ '


1
จำนวนมาก "ฉัน" ไม่ใช่เนื้อหาของการโต้เถียงมากมาย และโดยวิธีการที่ข้อผิดพลาด "หยุด" การสร้างมีอะไรจะทำอย่างไรกับแบบคงที่และแบบไดนามิก หากคุณมีการทดสอบหน่วยและหนึ่งล้มเหลว "ของคุณสร้างเสีย" และหวังว่าจะไม่นำไปใช้กับการผลิตจนกว่าที่แก้ไข
nafg

อะไรทำให้คุณคิดว่าฉันบอกเป็นนัย ๆ ว่าอะไร?
nafg

ผลผลิตของคุณในจาวาสคริปต์ไม่ได้พุ่งสูงขึ้นเนื่องจากจาวาสคริปต์ขาดประเภท คุณเพิ่มประสิทธิภาพการทำงานพุ่งสูงขึ้นเพราะ C ++ และ C # เป็นภาษาที่หนักหน่วง Javascript + types จริง ๆ แล้วจะเพิ่มประสิทธิภาพการทำงานของคุณยิ่งขึ้นไปอีก ไม่มีใครบอกว่าจาวาสคริปต์เป็นไปไม่ได้สำหรับโครงการขนาดใหญ่ Javascript ในโครงการขนาดใหญ่สามารถทำได้อย่างแน่นอน อย่างไรก็ตามมันไม่เหมาะ การทดสอบหน่วยใช้แทนการตรวจสอบชนิดนอกจากนี้การทดสอบเครื่องยังครอบคลุมพื้นที่ จำกัด ในขณะที่การตรวจสอบประเภทมีพื้นที่ครอบคลุม 100%
Brian Yeh

1
@BrianYeh c ++ และ c # เป็นภาษาที่หนักเพราะมันอยู่กึ่งกลางประเภท ฉันเพิ่งเริ่มใช้ reactjs ที่งานของฉันและผลผลิตของฉันก็ลดลงอีกครั้งเนื่องจากมันใช้งานอย่างต่อเนื่องกับประเภทและส่วนประกอบ ถ้าคุณชอบประเภทและการทดสอบหน่วยเหมาะสำหรับคุณ เราทุกคนไม่ได้แบ่งปันรูปแบบการเขียนโปรแกรมนี้

1
@foreyez reactjs ไม่มีประเภท คุณอาจหมายถึงการไหล การทดสอบหน่วยใช้แทนการตรวจสอบประเภทดังนั้นหากคุณไม่มีการตรวจสอบประเภทคุณจำเป็นต้องมีการทดสอบหน่วยเพิ่มเติม การทดสอบหน่วยและประเภทต่าง ๆ กำลังต่อต้าน ผลผลิตของคุณลดลงเป็นภาพลวงตา ข้อผิดพลาดประเภทใด ๆ ที่คุณพบในภาษาที่ปลอดภัยประเภทนั้นเป็นข้อผิดพลาดที่ไม่ได้ตรวจจับในภาษาที่พิมพ์แบบไดนามิก มันจะปรากฏขึ้นเร็วขึ้น ภาษาที่ปลอดภัยประเภทบังคับให้คุณต้องจัดการกับข้อผิดพลาดเหล่านั้นล่วงหน้า
Brian Yeh

0

ใช่.

ฉันทำงานในแอปพลิเคชั่น PHP โดยที่ประเภทไม่ "แข็งแกร่ง" เหมือนใน Java หรือ C # ฉันมักจะเสร็จสิ้น "การจำลองประเภท" เพราะเพื่อหลีกเลี่ยงการแปลงอัตโนมัติที่ไม่ดีหรือการตรวจสอบข้อมูล

ภาษาของ Dynamic Type นั้นดีสำหรับสคริปต์ของ OS และแอปขนาดเล็กอย่างรวดเร็วไม่ใช่แอพที่ซับซ้อน

สรุป: ถ้าผมต้องเลือกระหว่าง "อ่อนแอประเภท" หรือ "ไดนามิคประเภท" ภาษาการเขียนโปรแกรมหรือ "Strong ประเภท" การเขียนโปรแกรมภาษาที่ซับซ้อนการประยุกต์ทางธุรกิจผมเลือก"Strong ประเภท" การเขียนโปรแกรมภาษา


0

ฉันคิดว่าการจ่ายเงินจะใช้เวลาสักครู่และพิจารณาว่าการพิมพ์แบบไดนามิกทำให้เกิดปัญหาเมื่อใด

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

ปัญหาที่ลึกซึ้งยิ่งขึ้นอีกอย่างหนึ่งคือการทดแทนที่ไม่สมบูรณ์

หากประเภทนั้นผิดอย่างสิ้นเชิงเว้นแต่ว่าจะไม่มีการใช้พา ธ ของรหัสเฉพาะที่น่าจะตรวจพบได้อย่างรวดเร็ว

ในทางกลับกันถ้าประเภทเป็นตัวทดแทนที่ไม่สมบูรณ์รหัสนั้นอาจทำงานได้ แต่ส่วนใหญ่จะแตกในรูปแบบที่ละเอียดอ่อนซึ่งจะไม่ถูกตรวจพบจนกระทั่งในภายหลัง

สองประเภทที่พบบ่อยที่สุดในการเขียนโปรแกรมคือตัวเลขและสตริง ในแบบไดนามิกจำนวนมากพวกเขาจะทดแทนที่ไม่สมบูรณ์ซึ่งกันและกัน ในคำพูด javascript หรือ php หากคุณให้หมายเลขที่คาดว่าสตริงหรือในทางกลับกันโปรแกรมของคุณทำงานโดยไม่เพิ่มข้อผิดพลาด แต่สามารถทำงานผิดปกติในรูปแบบคำศัพท์ที่ค่อนข้าง

Python หลีกเลี่ยงปัญหาที่เกิดขึ้นโดยเฉพาะตัวเลขและสตริงไม่สามารถทดแทนกันได้และพยายามใช้อย่างใดอย่างหนึ่งซึ่งคาดว่าอีกอันหนึ่งจะนำไปสู่ความล้มเหลวอย่างรวดเร็ว

อย่างไรก็ตามมันก็ไม่ได้หลีกเลี่ยงปัญหา susbstituibility ที่ไม่สมบูรณ์อย่างสมบูรณ์ หมายเลขชนิดต่าง ๆ สามารถทดแทนกันได้ไม่สมบูรณ์ดังนั้นลำดับประเภทที่แตกต่างกันสามารถ


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

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