มีข้อได้เปรียบที่แท้จริงสำหรับภาษาไดนามิกหรือไม่ [ปิด]


29

ก่อนอื่นฉันอยากจะบอกว่า Java เป็นภาษาเดียวที่ฉันเคยใช้ดังนั้นโปรดขอโทษด้วยที่ฉันไม่รู้เรื่องนี้

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

void makeItBark(dog){
    dog.bark();
}

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

ดูเหมือนจะทำให้คุณมีความยืดหยุ่น

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

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

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

ฉันพลาดอะไรไปรึเปล่า? ฉันได้อะไรจากการใช้ภาษาที่พิมพ์แบบไดนามิก?


6
makeItBark(collections.namedtuple("Dog", "bark")(lambda x: "woof woof")). อาร์กิวเมนต์นั้นไม่ได้เป็นคลาสแต่เป็น tuple ที่ไม่ระบุชื่อ การพิมพ์เป็ด ("ถ้ามันเหมือน quacks ... ") ให้คุณทำส่วนต่อประสานเฉพาะกิจโดยไม่มีข้อ จำกัด เป็นศูนย์และไม่มีค่าใช้จ่ายเกี่ยวกับวากยสัมพันธ์ คุณสามารถทำสิ่งนี้ในภาษาเช่น Java แต่คุณก็มีภาพสะท้อนที่ยุ่งเหยิงมากมาย ถ้าฟังก์ชั่นใน Java ต้องการ ArrayList และคุณต้องการให้คอลเลกชันประเภทอื่นแสดงว่าคุณเป็น SOL ในงูหลามที่ไม่สามารถเกิดขึ้นได้
Phoshi

2
ชนิดของคำถามนี้ได้รับการถามก่อน: ที่นี่ , ที่นี่และที่นี่ ตัวอย่างแรกโดยเฉพาะดูเหมือนว่าจะตอบคำถามของคุณ บางทีคุณสามารถใช้ถ้อยคำใหม่เพื่อทำให้ชัดเจน?
logc

3
โปรดทราบว่าตัวอย่างเช่นใน C ++ คุณสามารถมีฟังก์ชั่นเทมเพลตที่ทำงานกับประเภท T ที่มีbark()วิธีการโดยคอมไพเลอร์บ่นเมื่อคุณผ่านสิ่งผิดปกติ แต่ไม่จำเป็นต้องประกาศอินเทอร์เฟซที่มีเปลือกไม้ ()
Wilbert

2
@Phoshi อาร์กิวเมนต์ใน Python ยังคงต้องเป็นประเภทเฉพาะ - ตัวอย่างเช่นมันไม่สามารถเป็นตัวเลขได้ หากคุณมีการดำเนินงานเฉพาะกิจของคุณเองของวัตถุซึ่งดึงสมาชิกผ่านที่กำหนดเองบางgetMemberฟังก์ชั่นmakeItBarkพัดขึ้นเพราะคุณเรียกแทนdog.bark dog.getMember("bark")สิ่งที่ทำให้โค้ดทำงานคือทุกคนตกลงที่จะใช้ประเภทวัตถุดั้งเดิมของ Python โดยปริยาย
Doval

2
@Phoshi Just because I wrote makeItBark with my own types in mind doesn't mean you can't use yours, wheras in a static language it probably /does/ mean that.เป็นแหลมออกในคำตอบของฉันนี้เป็นกรณีที่ไม่ทั่วไป นี่เป็นกรณีสำหรับ Java และ C # แต่ภาษาเหล่านั้นมีระบบคนพิการและระบบโมดูลดังนั้นพวกเขาจึงไม่ได้เป็นตัวแทนของการพิมพ์แบบสแตติกที่สามารถทำได้ ฉันสามารถเขียนแบบทั่วไปอย่างสมบูรณ์แบบmakeItBarkในหลายภาษาที่พิมพ์แบบสแตติกแม้แต่ภาษาที่ไม่สามารถใช้งานได้เช่น C ++ หรือ D
Doval

คำตอบ:


35

ภาษาที่พิมพ์แบบไดนามิกนั้นเป็นแบบ uni-typed

เมื่อเปรียบเทียบกับระบบประเภทแล้วไม่มีข้อได้เปรียบในการพิมพ์แบบไดนามิก การพิมพ์แบบไดนามิกเป็นกรณีพิเศษของการพิมพ์แบบคงที่ - เป็นภาษาที่พิมพ์แบบคงที่ซึ่งทุกตัวแปรมีชนิดเดียวกัน คุณสามารถบรรลุสิ่งเดียวกันใน Java (ลบความกระชับ) โดยทำให้ทุกตัวแปรเป็นประเภทObjectและมีค่า "วัตถุ" เป็นประเภทMap<String, Object>:

void makeItBark(Object dog) {
    Map<String, Object> dogMap = (Map<String, Object>) dog;
    Runnable bark = (Runnable) dogMap.get("bark");
    bark.run();
}

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

ทำเปลือกเป็ดในภาษาที่พิมพ์แบบคงที่

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

class Barkable a where
    bark :: a -> unit

สิ่งนี้เป็นการแสดงออกถึงข้อ จำกัด ที่บางประเภทaจะพิจารณาว่าเป็น Barkable จะต้องมีbarkฟังก์ชันที่รับค่าของประเภทนั้นและไม่ส่งคืนอะไรเลย

จากนั้นคุณสามารถเขียนฟังก์ชันทั่วไปในแง่ของBarkableข้อ จำกัด :

makeItBark :: Barkable a => a -> unit
makeItBark barker = bark (barker)

นี้กล่าวว่าmakeItBarkจะทำงานสำหรับประเภทใดที่น่าพอใจBarkable's ความต้องการ สิ่งนี้อาจดูเหมือนคล้ายกับinterfaceใน Java หรือ C # แต่มีข้อได้เปรียบใหญ่อย่างหนึ่ง - ประเภทไม่จำเป็นต้องระบุล่วงหน้าว่าคลาสชนิดใดที่พวกเขาพึงพอใจ ฉันสามารถพูดประเภทDuckนั้นBarkableได้ตลอดเวลาแม้ว่าDuckจะเป็นประเภทบุคคลที่สามที่ฉันไม่ได้เขียน ในความเป็นจริงมันไม่สำคัญว่าผู้เขียนDuckไม่ได้เขียนbarkฟังก์ชั่น - ฉันสามารถให้มันตามความเป็นจริงเมื่อฉันบอกภาษาที่DuckตรงกับBarkable:

instance Barkable Duck where
    bark d = quack (punch (d))

makeItBark (aDuck)

สิ่งนี้บอกว่าDucks สามารถเห่าและฟังก์ชั่นเปลือกของพวกเขาจะดำเนินการโดยการไล่เป็ดก่อนที่จะต้มตุ๋น เมื่อพ้นทางเราสามารถเรียกmakeItBarkเป็ดได้

Standard MLและOCamlมีความยืดหยุ่นมากขึ้นในการที่คุณสามารถตอบสนองประเภทคลาสเดียวกันได้มากกว่าหนึ่งวิธี ในภาษาเหล่านี้ฉันสามารถพูดได้ว่าจำนวนเต็มสามารถสั่งซื้อโดยใช้การสั่งซื้อแบบเดิมแล้วหมุนไปรอบ ๆ และบอกว่าพวกเขายังสามารถเรียงลำดับได้ด้วยการหาร (เช่น10 > 5เพราะ 10 หารด้วย 5) ใน Haskell คุณสามารถสร้างคลาสประเภทได้ครั้งเดียวเท่านั้น (นี้จะช่วยให้ Haskell จะรู้โดยอัตโนมัติว่ามันโอเคที่จะเรียกbarkในเป็ด; ใน SML หรือ OCaml คุณจะต้องมีความชัดเจนเกี่ยวกับที่ barkทำงานคุณต้องการเพราะอาจจะมีมากกว่าหนึ่ง.)

ความรัดกุม

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

โปรแกรมที่ถูกต้อง แต่พิมพ์ผิด

เพื่อความเป็นธรรมการพิมพ์สแตติกจำเป็นต้องออกกฎบางโปรแกรมที่ถูกต้องทางเทคนิคแม้ว่าตัวตรวจสอบประเภทจะไม่สามารถตรวจสอบได้ ตัวอย่างเช่น:

if this_variable_is_always_true:
    return "some string"
else:
    return 6

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

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

แอปเปิ้ลและส้ม

สุดท้ายอย่าลืมว่าภาษามีความแตกต่างมากกว่าระบบประเภทของพวกเขา ก่อนที่จะมี Java 8 ทำใด ๆชนิดของโปรแกรมการทำงานในชวาเป็นไปไม่ได้ในทางปฏิบัติ; แลมบ์ดาง่าย ๆ จะต้องใช้รหัสคลาส 4 บรรทัดที่ไม่ระบุชื่อสำเร็จรูป Java ยังไม่สนับสนุนตัวอักษรสำหรับการรวบรวม (เช่น[1, 2, 3]) นอกจากนี้ยังอาจมีความแตกต่างในด้านคุณภาพและความพร้อมของเครื่องมือ (IDE, debuggers), ไลบรารีและการสนับสนุนชุมชน เมื่อมีคนอ้างว่ามีประสิทธิผลมากขึ้นใน Python หรือ Ruby มากกว่า Java ต้องคำนึงถึงความแตกต่างของคุณลักษณะนั้น มีความแตกต่างระหว่างการเปรียบเทียบเป็นภาษาที่มีแบตเตอรี่ทั้งหมดรวม , แกนภาษาและระบบการพิมพ์


2
คุณลืมที่จะระบุแหล่งที่มาของคุณสำหรับย่อหน้าแรก - existentialtype.wordpress.com/2011/03/19/ …

2
@ Matt Re: 1 ฉันไม่ได้คิดว่ามันไม่สำคัญ ฉันพูดภายใต้ความกระชับ Re: 2 แม้ว่าฉันไม่เคยพูดอย่างชัดเจนโดย "ดี" ฉันหมายถึง "มีการอนุมานแบบละเอียด" และ "มีระบบโมดูลที่ช่วยให้คุณจับคู่โค้ดเพื่อพิมพ์ลายเซ็นหลังข้อเท็จจริง " ไม่ใช่หน้าแรกเช่น Java / อินเทอร์เฟซของ C # Re 3 ภาระในการพิสูจน์คือให้คุณอธิบายให้ฉันฟังว่าสองภาษาที่มีไวยากรณ์และคุณสมบัติเทียบเท่าหนึ่งประเภทที่มีการพิมพ์แบบไดนามิกและอื่น ๆ ที่มีการอนุมานแบบเต็มคุณจะไม่สามารถเขียนโค้ดที่มีความยาวเท่ากันได้ .
Doval

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

1
คุณควรดู Boo มันพิมพ์แบบคงที่ด้วยการอนุมานประเภทและมีแมโครที่ช่วยให้ไวยากรณ์ของภาษาที่จะขยาย
Mason Wheeler

1
@Doval: จริง BTW สัญกรณ์แลมบ์ดาไม่ได้ใช้เฉพาะในการเขียนโปรแกรมการทำงาน: เท่าที่ฉันรู้ Smalltalk มีบล็อกที่ไม่ระบุชื่อและ Smalltalk เป็นวัตถุเชิงที่จะได้รับ ดังนั้นบ่อยครั้งที่การแก้ปัญหาคือการส่งบล็อคโค้ดโดยไม่ระบุชื่อพร้อมพารามิเตอร์บางตัวไม่ว่าจะเป็นฟังก์ชั่นที่ไม่ระบุชื่อหรือวัตถุที่ไม่ระบุตัวตนด้วยวิธีการที่ไม่ระบุชื่ออย่างแน่นอน ฉันคิดว่าโครงสร้างทั้งสองนี้แสดงความคิดเดียวกันจากมุมมองที่แตกต่างกันสองประการ (หน้าที่การใช้งานและเชิงวัตถุ)
Giorgio

11

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

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

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

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

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

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

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


3
ขอบคุณสำหรับคำตอบ. คุณบอกว่าคอมไพเลอร์ไม่ชอบบางคนบอกว่าจะทำอย่างไร [.. ] พวกเขาชอบสไตล์การเขียนโปรแกรมเชิงสำรวจที่คุณเขียนรหัสธุรกิจจริงโดยไม่ต้องมีแผนที่จะบอกคุณว่าประเภทและข้อโต้แย้งที่จะใช้ที่ไหน ' นี่คือสิ่งที่ฉันไม่เข้าใจ: การเขียนโปรแกรมไม่เหมือนการกระทำทางดนตรี ในเพลงถ้าคุณกดผิดมันอาจฟังดูเย็น ในการเขียนโปรแกรมหากคุณส่งบางสิ่งบางอย่างไปยังฟังก์ชั่นที่ไม่ควรอยู่ที่นั่นคุณมักจะได้รับข้อบกพร่องที่น่ารังเกียจ (ดำเนินการต่อในความคิดเห็นถัดไป)
Aviv Cohn

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

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

1
ผู้คนมักพูดถึงโครงการประเภทต่างๆ (โดยเฉพาะเกี่ยวกับขนาด) ตรรกะทางธุรกิจสำหรับเว็บไซต์จะง่ายมากเมื่อเทียบกับระบบ ERP แบบเต็ม มีความเสี่ยงน้อยกว่าที่คุณจะได้รับสิ่งผิดปกติและข้อดีของความสามารถในการนำรหัสมาใช้ซ้ำบางครั้งมีความเกี่ยวข้องมากขึ้น สมมติว่าฉันมีรหัสที่สร้าง Pdf (หรือ HTML บางส่วน) จากโครงสร้างข้อมูล ตอนนี้ฉันมีแหล่งข้อมูลที่แตกต่างกัน (อันดับแรกคือ JSON จาก REST API บางส่วนตอนนี้เป็นผู้นำเข้า Excel) ในภาษาอย่าง Ruby มันสามารถ 'จำลอง' โครงสร้างแรกได้ง่ายมาก 'ทำให้มันเห่า' และใช้รหัส Pdf อีกครั้ง
thorsten müller

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

5

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

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


2
ผู้คนมักจะใช้ระบบประเภทคงที่พื้นฐานอีกครั้งกับการทดสอบหน่วยของพวกเขาในที่สุด (เมื่อกำหนดเป้าหมายความครอบคลุมการทดสอบที่ดี)
Den

นอกจากนี้คุณหมายถึงอะไรโดย "แต่งงานกัน" ที่นี่? มันจะแสดงให้เห็นอย่างไรในสถาปัตยกรรมเช่นบริการไมโคร?
Den

@Den 1) คำถามที่ดี แต่ฉันรู้สึกว่ามันอยู่นอกขอบเขตของ OP และคำตอบของฉัน 2) ผมหมายถึงการมีเพศสัมพันธ์ในความรู้สึกนี้ ; สั้น ๆ ระบบประเภทที่แตกต่างกันกำหนดข้อ จำกัด (เข้ากันไม่ได้) ที่แตกต่างกันในรหัสที่เขียนในภาษานั้น ขออภัยฉันไม่สามารถตอบคำถามสุดท้าย - ฉันไม่เข้าใจว่ามีอะไรพิเศษเกี่ยวกับบริการไมโครในเรื่องนี้

2
@Den: จุดที่ดีมาก: ฉันมักจะสังเกตเห็นว่าการทดสอบหน่วยฉันเขียนข้อผิดพลาดที่ครอบคลุม Python ที่จะรวบรวมโดยคอมไพเลอร์ในภาษาที่พิมพ์แบบคงที่
Giorgio

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