डायनामिक-टाइप की गई भाषाएं यूनि-टाइप की जाती हैं
टाइप सिस्टम की तुलना में, गतिशील टाइपिंग में कोई फायदा नहीं है। डायनेमिक टाइपिंग स्टैटिक टाइपिंग का एक विशेष मामला है - यह एक स्टेटिक-टाइप की गई भाषा है जहाँ हर वेरिएबल में एक ही प्रकार होता है। आप प्रत्येक चर प्रकार के होने के द्वारा जावा (माइनस कंसिस्टेंसी) में एक ही चीज प्राप्त कर सकते हैं 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
ऑपरेशन होता है। हास्केल में, यह एक प्रकार का वर्ग है:
class Barkable a where
bark :: a -> unit
यह बाधा व्यक्त करता है कि कुछ प्रकार a
को बार्केबल माना जाता है, एक bark
फ़ंक्शन मौजूद होना चाहिए जो उस प्रकार का मान लेता है और कुछ भी नहीं लौटाता है।
फिर आप Barkable
बाधा के संदर्भ में सामान्य कार्य लिख सकते हैं :
makeItBark :: Barkable a => a -> unit
makeItBark barker = bark (barker)
यह कहता है कि makeItBark
किसी भी प्रकार की संतोषजनक Barkable
आवश्यकताओं के लिए काम करेगा । यह एक के समान लग सकता है interface
जावा या सी # में है, लेकिन यह एक बड़ा फायदा है - प्रकार निर्दिष्ट करने के लिए की जरूरत नहीं है सामने किस प्रकार कक्षाएं वे पूरा करते हैं। मैं कह सकता हूँ कि प्रकार Duck
है Barkable
किसी भी समय है, भले ही Duck
एक तीसरे पक्ष के प्रकार मैं नहीं लिखा था है। वास्तव में, यह फर्क नहीं पड़ता कि के लेखक Duck
एक नहीं लिखा था bark
समारोह - जब मैं भाषा कि बताओ मैं बाद-तथ्य यह प्रदान कर सकते हैं Duck
को संतुष्ट करता है Barkable
:
instance Barkable Duck where
bark d = quack (punch (d))
makeItBark (aDuck)
यह कहता है कि Duck
s छाल कर सकते हैं, और उनके छाल कार्य को चुटकी बनाने से पहले बतख को छिद्रित करके कार्यान्वित किया जाता है । उस रास्ते से, हम makeItBark
बतख पर कॉल कर सकते हैं।
Standard ML
और OCaml
इसमें और भी अधिक लचीला है कि आप एक ही प्रकार के वर्ग को एक से अधिक तरीकों से संतुष्ट कर सकते हैं । इन भाषाओं में मैं कहता हूं कि पूर्णांकों पारंपरिक आदेश का उपयोग कर आदेश दिया जा सकता है और फिर बिलकुल पलट गया और कहते हैं कि वे कर रहे हैं कर सकते हैं भी विभाज्यता द्वारा orderable (जैसे 10 > 5
क्योंकि 10 5 से विभाज्य है)। हास्केल में आप केवल एक बार क्लास टाइप कर सकते हैं। (इससे हास्केल को स्वचालित रूप से पता चल जाता है कि bark
बतख पर कॉल करना ठीक है ; एसएमएल या ओकेएमएल में आपको स्पष्ट होना चाहिए कि आप किस bark
फ़ंक्शन को चाहते हैं, क्योंकि एक से अधिक हो सकते हैं।)
संक्षिप्ति
बेशक, वाक्यात्मक अंतर है। आपके द्वारा प्रस्तुत पायथन कोड मेरे द्वारा लिखे गए जावा समकक्ष की तुलना में कहीं अधिक संक्षिप्त है। व्यवहार में, यह संक्षिप्तता गतिशील रूप से टाइप की जाने वाली भाषाओं के आकर्षण का एक बड़ा हिस्सा है। लेकिन टाइप इंफ़ेक्शन आपको कोड लिखने की अनुमति देता है जो वैधानिक रूप से टाइप की जाने वाली भाषाओं में संक्षिप्त है, आपको प्रत्येक चर के प्रकारों को स्पष्ट रूप से लिखने के लिए राहत देता है । एक सांख्यिकीय रूप से टाइप की गई भाषा डायनामिक टाइपिंग के लिए मूल समर्थन भी प्रदान कर सकती है, सभी कास्टिंग और मानचित्र जोड़तोड़ (जैसे C # 's dynamic
) की क्रियाशीलता को हटा सकती है ।
सही लेकिन बीमार टाइप के कार्यक्रम
निष्पक्ष होने के लिए, स्टैटिक टाइपिंग जरूरी कुछ कार्यक्रमों को नियमबद्ध करता है जो तकनीकी रूप से सही होते हैं भले ही टाइप चेकर इसे सत्यापित न कर सके। उदाहरण के लिए:
if this_variable_is_always_true:
return "some string"
else:
return 6
अधिकांश स्टेटिक-टाइप की गई भाषाएं इस if
कथन को अस्वीकार कर देंगी , भले ही दूसरी शाखा कभी नहीं होगी। व्यवहार में ऐसा लगता है कि कोई भी इस प्रकार के कोड का उपयोग नहीं करता है - टाइप चेकर के लिए बहुत चालाक कुछ भी आपके कोड के भविष्य को बनाए रखने के लिए आपको और आपके परिजनों को शाप देगा। इस मामले में, किसी ने हास्केल में 4 ओपन सोर्स पायथन प्रोजेक्ट्स का सफलतापूर्वक अनुवाद किया , जिसका अर्थ है कि वे ऐसा कुछ भी नहीं कर रहे थे जो एक अच्छी तरह से टाइप की गई भाषा संकलित न कर सके। क्या अधिक है, संकलक ने कुछ प्रकार के संबंधित बग पाए जो इकाई परीक्षण नहीं पकड़ रहे थे।
डायनेमिक टाइपिंग के लिए मैंने जो सबसे मजबूत तर्क देखा है, वह है लिस्प का मैक्रोज़, क्योंकि वे आपको भाषा के सिंटैक्स का मनमाना विस्तार करने की अनुमति देते हैं। हालाँकि, टाइप रैकेट , लिस्प की एक सांख्यिकीय-टाइप की गई बोली है जिसमें मैक्रोज़ हैं, इसलिए ऐसा लगता है कि स्थैतिक टाइपिंग और मैक्रोज़ पारस्परिक रूप से अनन्य नहीं हैं, हालांकि एक साथ लागू करने के लिए शायद कठिन है।
सेब और संतरे
अंत में, यह न भूलें कि भाषाओं में उनके प्रकार के सिस्टम की तुलना में बड़े अंतर हैं। जावा 8 से पहले, जावा में किसी भी प्रकार की कार्यात्मक प्रोग्रामिंग करना व्यावहारिक रूप से असंभव था; एक साधारण मेमने को बॉयलरप्लेट अनाम वर्ग कोड की 4 लाइनों की आवश्यकता होगी। जावा के पास संग्रह शाब्दिकों (जैसे [1, 2, 3]
) के लिए कोई समर्थन नहीं है । टूलींग की गुणवत्ता और उपलब्धता (आईडीई, डीबगर्स), पुस्तकालयों और सामुदायिक समर्थन में भी अंतर हो सकता है। जब किसी ने जावा की तुलना में पायथन या रूबी में अधिक उत्पादक होने का दावा किया, तो उस सुविधा असमानता को ध्यान में रखा जाना चाहिए। सभी बैटरियों में शामिल भाषाओं , भाषा कोर और टाइप सिस्टम के साथ तुलना करने में अंतर है ।
makeItBark(collections.namedtuple("Dog", "bark")(lambda x: "woof woof"))
। यह तर्क एक वर्ग भी नहीं है , यह एक अनाम नाम है। बत्तख टाइपिंग ("अगर यह एक तरह से बंद हो जाता है ...") आपको अनिवार्य रूप से शून्य प्रतिबंध और कोई सिंटैक्टिक ओवरहेड के साथ तदर्थ इंटरफेस नहीं करने देता है। आप इसे जावा जैसी भाषा में कर सकते हैं, लेकिन आप बहुत सारे गंदे प्रतिबिंब के साथ समाप्त होते हैं। यदि जावा में एक फ़ंक्शन के लिए एक ArrayList की आवश्यकता होती है और आप इसे एक और संग्रह प्रकार देना चाहते हैं, तो आप SOL हैं। अजगर में जो ऊपर भी नहीं आ सकता है।