มีข้อโต้แย้งอะไรในความโปรดปรานของการพิมพ์ที่อ่อนแอ?


40

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


17
วิศวกรรมคอมไพเลอร์ของ Cooper และ Torczon นิยามการพิมพ์ที่อ่อนแอโดยใช้ระบบพิมพ์ที่ออกแบบมาไม่ดี แน่นอนว่าไม่ฟังดูเหมือนว่าจะเป็นประโยชน์กับทุกคน
Corbin วันที่

@Corbin มีนาคม: Nice one ฉันต้องเพิ่มเข้าไปในรายการของฉัน
Jörg W Mittag

5
ข้อโต้แย้งที่ดีที่สุดสามารถให้ได้โดยผู้บริหารองค์กร: ช่วยให้ฉันสามารถจ้างคนราคาถูกเพื่อสร้างระบบของฉัน
Vector

คำตอบ:


46

ปัญหาของการสนทนาประเภทนี้ก็คือคำว่า "การพิมพ์ที่ไม่รัดกุม" และ "การพิมพ์ที่รัดกุม" นั้นไม่ได้กำหนดซึ่งแตกต่างจากตัวอย่างเช่นคำว่า "การพิมพ์แบบคงที่", "การพิมพ์แบบไดนามิก", "การพิมพ์แบบชัดแจ้ง", "การพิมพ์แบบชัดแจ้ง" การพิมพ์เป็ด "," การพิมพ์เชิงโครงสร้าง "หรือ" การพิมพ์เล็กน้อย " Heck แม้คำว่า "การพิมพ์อย่างชัดแจ้ง" และ "การพิมพ์แบบแฝง" ซึ่งยังคงเป็นพื้นที่เปิดของการวิจัยและการอภิปรายอาจมีการกำหนดไว้ดีกว่า

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

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

คำจำกัดความที่ใช้บ่อยบางคำคือ (และใช่ฉันรู้ว่าไม่มีคำอธิบายใด ๆ ที่สมเหตุสมผล แต่เป็นคำจำกัดความที่ฉันเคยเห็นคนใช้จริง):

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

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

  • อ่อนแอการพิมพ์ = ภาษาการเขียนโปรแกรมเส็งเคร็งของคุณ / การพิมพ์ที่แข็งแกร่ง = ภาษาการเขียนโปรแกรมที่ยอดเยี่ยมของฉัน
  • อ่อนแอการพิมพ์ = ภาษาการเขียนโปรแกรมอื่น ๆ ทุกชนิด / การพิมพ์ที่แข็งแกร่ง = ภาษาการเขียนโปรแกรมเพียงอย่างเดียวที่ฉันเคยใส่ใจที่จะเรียนรู้ (โดยปกติคือ Java, C # หรือ C ++; โลกทัศน์นี้)
  • อ่อนแอการพิมพ์ = ทุกภาษาที่ฉันไม่เข้าใจ / การพิมพ์แรง = Java (แทนที่ด้วย C # หรือ C ++ ที่จะ)

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

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


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

7
@Renesis: ฉันจะเรียกมันว่า "ความจริง" :-) ฉันได้เห็นการอภิปรายเกี่ยวกับระบบการพิมพ์มากพอที่จะรู้ว่าครึ่งหนึ่งของคนไม่รู้ว่าพวกเขากำลังพูดถึงสิ่งที่แตกต่างอย่างสิ้นเชิงและอีกคนไม่รู้ว่าพวกเขากำลังพูดถึงอะไร เกี่ยวกับการที่ทุกคน สองสามเดือนที่ผ่านมามีการอภิปรายในรายการการพัฒนาหลักของภาษาที่ฉันจะไม่ตั้งชื่อเกี่ยวกับการเพิ่มระบบประเภททางเลือกเพื่อปรับปรุงประสิทธิภาพ การสนทนาดังกล่าวดำเนินไปเป็นเวลาหนึ่งสัปดาห์มีผู้คนเข้ามาเกี่ยวข้องหลายสิบคนและมีจดหมายหลายร้อยฉบับ ไม่มีใครตระหนักว่าระบบประเภทที่เป็นตัวเลือกตามคำนิยามไม่สามารถปรับปรุงประสิทธิภาพได้ …
Jörg W Mittag

8
+1 สำหรับความเห็นถากถางดูถูก! คุณอาจเพิ่ม "strong การพิมพ์ = เมื่อ IDE รู้ชนิดของตัวแปรของฉัน (Intellisense ฯลฯ ), การพิมพ์ที่อ่อนแอ = เมื่อไม่มี)"
281377

1
ชื่อที่ดีกว่าที่กำหนดไว้สำหรับระบบการพิมพ์ที่ขาดวิจารณญาณค่านัยที่อ่อนแอและแข็งแกร่งมี
Eva

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

25

โปรดจำไว้ว่ามีแนวคิดหลักสองข้อที่มักสับสน:

การพิมพ์แบบไดนามิก

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

ข้อดีที่นี่มักจะถูกไล่ออกเหมือนกับโปรแกรมเมอร์ "ใหม่" แต่ก็สามารถอำนวยความสะดวกให้กับโปรแกรมเมอร์ได้:

if (!(arr is Array)) arr = [arr]; // is, instanceof, .constructor ==, whatever

โค้ดน้อยลงในกรณีใด ๆ ที่คุณต้องโยนหรือกำหนดค่าใหม่:

if (data is Array)) {
    i = data.length; // no i = ((Array)data).length or Array myArr=(Array)data;
}

การพิมพ์ที่หลวมหรืออ่อนแอ

การพิมพ์ที่อ่อนแอหมายถึงภาษาที่แปลงประเภท (หรือปลดเปลื้อง) โดยนัยเมื่อใช้

ประโยชน์ที่ได้รับ:

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

    var a = param || defaultValue;
    
  • อีกครั้งรหัสน้อย:

    var num = 5;
    var str = "Hello";
    input.innerHTML = input.value = num;
    for (var i=0; i < input.value; i++) { ... }
    

    แม้กระทั่งจาวาก็ต้องไปครึ่งทางด้วยการเรียกโดยปริยาย.toString()เมื่อรวมวัตถุกับString; มิฉะนั้นโปรแกรมเมอร์ Java จะสาปแช่งตลอดทั้งวัน (งบงบจะออกจากการควบคุม)


คำจำกัดความของทั้งสองมาจากhttp://en.wikipedia.org/wiki/Type_system มันบอกว่ามันดีกว่าที่ฉันจะทำได้


1
การพิมพ์แบบไดนามิกยังมีประโยชน์ในกรณีที่จำเป็นต้องสร้างรหัสจำนวนมากในภาษาที่พิมพ์แบบคงที่ เปรียบเทียบปริมาณการสร้างรหัสที่จำเป็นสำหรับการพูดเอนทิตี Framework ในไลบรารี C # กับ ORM ในภาษาที่พิมพ์แบบไดนามิก (PHP, Python และอื่น ๆ ) แม้ว่าบางคนอาจเถียงว่าผลประโยชน์ในแง่ของการ IntelliSense IDE เมื่อเทียบกับค่าใช้จ่ายของทุกคนที่สร้างรหัส ...
คณบดีฮาร์ดิ้ง

3
ความคิดเห็นของคุณ "// no i = ข้อมูล (Array)) .length หรือ Array myArr = (Array) data;" ไม่ได้เกี่ยวอะไรกับการพิมพ์แบบไดนามิกเพราะอาเรย์ของข้อมูลสามารถพิสูจน์ได้ในเวลาคอมไพล์ ภาษาที่พิมพ์แบบสแตติกสามารถเผยแพร่ความรู้ที่ได้จากอินสแตนซ์ของ
ปีเตอร์เทย์เลอร์

@ Peter Taylor ฉันคิดว่ามันเป็นจริงในกรณีง่าย ๆ คุณรู้หรือไม่ว่าทำเช่นนั้น? มันจะต้องทำอย่างไรกับการพิมพ์แบบไดนามิกที่ไม่ว่าจะใช้ifบล็อกหรือตรรกะที่ซับซ้อนมากขึ้น (แม้กระทั่งรันไทม์หรือแบบไดนามิก) บรรทัดถัดไปจะถูกกฎหมายและปลอดภัยจากข้อผิดพลาด
Nicole

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

1
@Peter Taylor ถูกต้อง ประโยชน์ของการพิมพ์แบบไดนามิกจำนวนมากมีให้บริการในภาษาที่มีระบบการพิมพ์แบบคงที่ที่ดีกว่าเช่น Haskell, Scala หรือแม้แต่ C # ในบางกรณี ฉันจะบอกว่าข้อได้เปรียบที่สำคัญของการพิมพ์แบบไดนามิกคือการจัดการกับสิ่งที่พิมพ์โดยเนื้อแท้เช่น HTML DOM เหตุใดจึงต้องเขียนโหนด ["attr"] แทน node.attr พวกเขาจะได้รับการแก้ไขที่รันไทม์อยู่แล้ว
Matt Olenik

7

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

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

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

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

ที่กล่าวว่าในกรณีส่วนใหญ่มีระบบประเภทที่แข็งแกร่งที่มีการตรวจสอบเวลารวบรวมหรือตรวจสอบ runtime ช่วยบ่อยกว่าเจ็บ


2
ฉันไม่เห็นว่าทำไมภาษาที่พิมพ์อย่างรุนแรงไม่สามารถรวบรวมได้อย่างมีประสิทธิภาพเท่า C. แต่คอมไพเลอร์ควรมีความซับซ้อนมากขึ้นอย่างมากมาย
9000

2
C ++ เป็นตัวอย่างหนึ่งของภาษาดังกล่าว ใน C ++ การตรวจสอบทุกประเภทเสร็จสิ้น ณ เวลารวบรวมและไม่มีการดำเนินการใด ๆ ในขณะดำเนินการ ... จนกว่าคุณจะเปิดใช้งาน RTTI
Berin Loritsch

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

2

การพิมพ์ที่อ่อนแอนั้นง่ายกว่าสำหรับมือใหม่ที่จะเข้าใจเช่นในสิ่งต่าง ๆ เช่น excel, javascript และ vbscript คุณสามารถแลกเปลี่ยนความเร็วในการพัฒนาเพื่อหาข้อผิดพลาดที่อาจเกิดขึ้น

บทความที่ดีเกี่ยวกับเรื่อง: การพิมพ์ที่แข็งแกร่งและการทดสอบที่แข็งแกร่ง


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

ไม่ไม่ใช่ภาษาโดยทั่วไปฉันแค่พูดถึงการพิมพ์
Homde

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

3
@Mchl: นั่นไม่มีส่วนเกี่ยวข้องกับการพิมพ์คงที่ / ไดนามิกหรือการพิมพ์ที่แข็งแกร่ง / อ่อนแอ การประกาศประเภทเป็นเรื่องเกี่ยวกับการพิมพ์ที่ชัดเจน / โดยนัย
Jörg W Mittag

1
อาจจะเป็นเช่นกัน;) ดังนั้นฉันจึงย้ายจากภาษาที่ชัดเจนเป็นภาษาที่พิมพ์โดยปริยาย ถูกต้องฉันถ้าฉันผิด Pascal เป็นแบบคงที่พิมพ์อย่างชัดเจนและชัดเจนในขณะที่ PHP เป็นแบบไดนามิกอ่อนแอและพิมพ์โดยนัยใช่มั้ย
Mchl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.