क्रमिक टंकण: "लगभग हर भाषा में एक स्थिर प्रकार की प्रणाली भी एक गतिशील प्रकार की प्रणाली होती है"


20

एलेक्स ब्रोमफील्ड का यह दावा है :

स्टैटिक टाइप सिस्टम वाली लगभग हर भाषा में डायनामिक टाइप सिस्टम भी होता है। सी के अलावा, मैं एक अपवाद के बारे में नहीं सोच सकता

क्या यह वैध दावा है? मैं समझता हूं कि रनटाइम के दौरान परावर्तन या लोडिंग कक्षाओं के साथ जावा को थोड़ा सा मिलता है - लेकिन क्या 'क्रमिक टाइपिंग' के इस विचार को बड़ी संख्या में भाषाओं में विस्तारित किया जा सकता है?


मैं कोई भाषा विशेषज्ञ नहीं हूं, लेकिन कुछ लोगों के दिमाग में यह बात आती है कि मुझे विश्वास नहीं है कि मेरे पास डायनेमिक प्रकार नहीं हैं (मूल रूप से, यह कहते हुए कि आप इनमें से कुछ एक साथ नहीं कर सकते) - फोरट्रान, एडा, पास्कल, कोबोल
मैट्नोज़

4
मैं एक भाषा विशेषज्ञ हूं, और मुझे यकीन नहीं है कि यह आदमी क्या दावा कर रहा है। "स्टैटिक" और "डायनामिक" मिसनोमर्स हैं और आमतौर पर टाइप चेक / एनालिसिस के समय को दर्शाते हैं (चाहे संकलन समय पर या विस्तार पर)। कुछ भाषाएं दोनों को संकलित करती हैं (उदाहरण के लिए संकलन के दौरान असमर्थित प्रकारों पर संचालन को रोकना और रनटाइम के दौरान ClassCastException जैसे अपवादों को उठाना), और वह वही हो सकता है जिसका अर्थ है। यदि हां, तो यह सच है कि सी आमतौर पर रनटाइम के दौरान टाइप चेक नहीं करता है। एक लंगड़ा कह रहा है। "डायनेमिक टाइप सिस्टम" का कोई मतलब नहीं है।
थियागो सिल्वा

जवाबों:


37

मूल ट्वीटर यहाँ। :)

सबसे पहले, मैं कुछ हैरान हूँ / हैरान हूँ कि मेरे ट्वीट को इतनी गंभीरता से लिया जा रहा है! अगर मुझे पता था कि यह व्यापक रूप से प्रसारित होने जा रहा है, तो मैंने इसे लिखने में 30 सेकंड से अधिक खर्च किया होगा!

थियागो सिल्वा यह इंगित करने के लिए सही है कि "स्थिर" और "गतिशील" प्रकार की प्रणालियों के बजाय अधिक सटीक रूप से प्रकार की जाँच का वर्णन करते हैं । वास्तव में, यह कहना वास्तव में सटीक नहीं है कि एक भाषा सांख्यिकीय या गतिशील रूप से टाइप की जाती है। इसके बजाय, एक भाषा में एक प्रकार की प्रणाली होती है, और उस भाषा का कार्यान्वयन स्थैतिक जाँच, या गतिशील जाँच, या दोनों का उपयोग करके प्रकार प्रणाली को लागू कर सकता है, या न ही (हालांकि यह बहुत आकर्षक भाषा कार्यान्वयन नहीं होगा!)।

जैसा कि होता है, कुछ प्रकार के सिस्टम (या टाइप सिस्टम के फीचर्स) होते हैं, जो स्थैतिक जाँच के लिए अधिक उत्तरदायी होते हैं, और कुछ प्रकार के सिस्टम (या टाइप सिस्टम के फीचर्स) होते हैं, जो गतिशील जाँच के लिए अधिक उत्तरदायी होते हैं। उदाहरण के लिए, यदि आपकी भाषा आपको एक कार्यक्रम के पाठ में निर्दिष्ट करने की अनुमति देती है कि एक विशेष मूल्य हमेशा पूर्णांक का एक सरणी होना चाहिए, तो उस संपत्ति को सत्यापित करने के लिए एक स्थिर चेकर लिखने के लिए यह उचित रूप से सीधा है। इसके विपरीत, यदि आपकी भाषा में सबटाइफ़िंग है, और यदि यह डाउनकास्टिंग की अनुमति देता है, तो यह रनटाइम पर डाउनकास्ट की वैधता की जांच करने के लिए उचित रूप से सरल है, लेकिन संकलन समय पर ऐसा करना बहुत कठिन है।

मेरे ट्वीट से मुझे वास्तव में जो मतलब था, वह यह है कि भाषा के बहुसंख्यक कार्यान्वयन कुछ मात्रा में गतिशील प्रकार की जाँच करते हैं। या, समान रूप से, भाषाओं के विशाल बहुमत में कुछ विशेषताएं हैं जो सांख्यिकीय रूप से जांचना मुश्किल (यदि असंभव नहीं है)। डाउनकास्टिंग एक उदाहरण है। अन्य उदाहरणों में अंकगणित अतिप्रवाह, सरणी सीमा जाँच, और अशक्त जाँच शामिल हैं। इनमें से कुछ को कुछ परिस्थितियों में सांख्यिकीय रूप से जांचा जा सकता है, लेकिन बड़े पैमाने पर, आपको एक भाषा कार्यान्वयन खोजने के लिए कड़ी मेहनत करनी होगी जो रनटाइम पर कोई जाँच नहीं करता है।

यह बुरी चीज़ नहीं है। यह सिर्फ एक अवलोकन है कि कई दिलचस्प गुण हैं जिन्हें हम अपनी भाषाओं को लागू करना चाहते हैं, और यह कि हम वास्तव में सांख्यिकीय रूप से जांचना नहीं जानते हैं। और यह याद दिलाता है कि "स्थिर प्रकार" बनाम "गतिशील प्रकार" जैसे अंतर लगभग स्पष्ट नहीं हैं क्योंकि कुछ लोग आपको विश्वास करेंगे। :)

एक अंतिम नोट: "मजबूत" और "कमजोर" शब्द का उपयोग वास्तव में प्रोग्रामिंग भाषा अनुसंधान समुदाय में नहीं किया जाता है, और उनका वास्तव में एक सुसंगत अर्थ नहीं है। सामान्य तौर पर, मैंने पाया है कि जब कोई कहता है कि किसी भाषा में "मजबूत टाइपिंग" है और किसी अन्य भाषा में "कमजोर टाइपिंग" है, तो वे वास्तव में कह रहे हैं कि उनकी पसंदीदा भाषा ("मजबूत टाइपिंग") उन्हें रोकती है कुछ ऐसी गलती करना जो दूसरी भाषा ("कमजोर टाइपिंग" वाली) नहीं है - या इसके विपरीत, कि उनकी पसंदीदा भाषा ("कमजोर टाइपिंग" वाली) उन्हें कुछ अच्छी चीज़ करने की अनुमति देती है जो कि दूसरी भाषा ( "मजबूत टाइपिंग" वाला) नहीं है।


9
"यह सिर्फ एक अवलोकन है कि कई दिलचस्प गुण हैं जिन्हें हम अपनी भाषाओं को लागू करना चाहते हैं, और यह कि हम वास्तव में सांख्यिकीय रूप से जांचना नहीं जानते हैं।" - ठीक है, यह सिर्फ इतना नहीं है कि हम नहीं जानते कि यह कैसे करना है। "क्या यह कार्यक्रम इस इनपुट के लिए रुकता है" एक दिलचस्प संपत्ति है जिसे हम न केवल जांचना जानते हैं, लेकिन वास्तव में हम जानते हैं कि यह जांचना असंभव है।
जोर्ग डब्ल्यू मित्तग

"अन्य उदाहरणों में अंकगणितीय अतिप्रवाह, सरणी सीमा जाँच और शून्य जाँच शामिल है।" बस ध्यान दें कि कुछ भाषाएं हैं जो टाइप सिस्टम में इन गुणों की जांच करती हैं, यहां तक ​​कि ज्यादातर गतिशील रूप से टाइप की जाने वाली भाषाओं में भी ये आमतौर पर मानों की एक विशेषता है , न कि प्रकार। ("नल" जाँच स्थैतिक प्रकार प्रणालियों की एक सामान्य विशेषता है।)
porglezomp

वहाँ है एक गतिशील प्रकार प्रणाली , और एक स्थिर प्रकार प्रणाली । यहां तक ​​कि अगर न तो लागू किया जाता है, तो वे अभी भी वहां हैं, यह वर्णन करते हुए कि क्या सही है और एक त्रुटि क्या है। भाषा / कार्यान्वयन उनमें से किसी की भी जाँच कर सकता है या नहीं भी कर सकता है। बीटीडब्ल्यू, स्थिर और गतिशील प्रकार की प्रणाली सुसंगत होनी चाहिए, लेकिन परिभाषा के अनुसार ऐसा नहीं है ।
एलजार

प्रत्येक भाषा में एक गतिशील प्रकार की प्रणाली होती है, जो कुछ कार्यों को निष्पादित करने से मना करने वाले नियमों का एक समूह है।
इलाजरत

7

सही है। आपके पास किसी भी वैधानिक रूप से टाइप की गई भाषा में प्रॉपर्टी बैग हो सकते हैं। सिंटैक्स भयानक होगा जबकि उसी समय आप गतिशील रूप से टाइप किए गए सिस्टम के सभी नुकसानों को प्राप्त करेंगे। इसलिए वास्तव में कोई फायदा नहीं है जब तक कि कंपाइलर आपको अच्छे सिंटैक्स का उपयोग करने की अनुमति नहीं देता है, सी # जैसा कुछ dynamicकर रहा है।

इसके अलावा, आप सी में भी बहुत आसानी से कर सकते हैं।

अन्य उत्तरों की प्रतिक्रिया में: मुझे लगता है कि लोग मजबूत / कमजोर टाइपिंग के साथ स्थिर / गतिशील टाइपिंग गलत कर रहे हैं। डायनामिक टाइपिंग रनटाइम पर डेटा की संरचना को बदलने में सक्षम है और उपयोग किए जा रहे डेटा को कोड करने में सक्षम है जो कि कोड की आवश्यकता के अनुरूप है। इसे डक टाइपिंग कहा जाता है ।

प्रतिबिंब का उल्लेख करना पूरी कहानी नहीं बता रहा है, क्योंकि प्रतिबिंब आपको डेटा की मौजूदा संरचना को बदलने की अनुमति नहीं देता है। आप C, C ++, Java या C # में किसी वर्ग या संरचना में नया क्षेत्र नहीं जोड़ सकते। गतिशील भाषाओं में, मौजूदा कक्षाओं में नए फ़ील्ड या विशेषताओं को जोड़ना न केवल संभव है, बल्कि वास्तव में काफी सामान्य है।

उदाहरण के लिए, साइथन , पायथन-टू-सी कंपाइलर को देखें। यह स्थिर C कोड बनाता है, लेकिन प्रकार की प्रणाली अभी भी इसे गतिशील प्रकृति बनाए रखती है। C सांख्यिकीय रूप से टाइप की गई भाषा है, फिर भी यह पायथन से गतिशील टाइपिंग का समर्थन करने में सक्षम है।


तकनीकी रूप से, आप इसे C # के साथ संस्करण 4 के रूप में कर सकते हैं ExpandoObject, हालांकि यह बहुत अधिक ऑप्ट-इन प्रक्रिया है, जावास्क्रिप्ट या रूबी के विपरीत। फिर भी, आपने एक बहुत ही महत्वपूर्ण बिंदु बनाया है, जो यह है कि बतख टाइपिंग (डेवलपर्स का 99% वास्तव में क्या मतलब है जब वे कहते हैं कि "गतिशील रूप से टाइप किया गया है") और प्रतिबिंब बिल्कुल समान चीजें नहीं हैं।
हारून ने

शायद मैं यह भी जोड़ूं कि पायथन में वास्तविक बतख टाइपिंग नहीं है। इसके लिए आपके पास "अपने स्वयं के कार्यान्वयन" के लिए कुछ हुक हैं (एक जादू की विधि है जो Trueयह कहने के लिए वापस आ सकती है कि "यह पागल वस्तु वर्ग का एक उदाहरण है जो मैं परिभाषित कर रहा हूं")। OCaml के पास यह सुविधा है जहाँ तक मैं समझता हूँ, लेकिन मैं वास्तव में नहीं जानता।
vlad-ardelean

6

गतिशील भाषाएं स्थिर भाषाएं हैं । जिसे आमतौर पर "डायनेमिक टाइपिंग" कहा जाता है, वह वास्तव में स्टेटिक टाइपिंग का एक विशेष मामला है - वह मामला जहां आपने खुद को केवल एक प्रकार के होने तक सीमित रखा है। एक विचार प्रयोग के रूप में, किसी भी विधि को Objectकॉल करने से पहले केवल चर / क्षेत्र / मापदंडों और डाउन-कास्टिंग का उपयोग करके जावा या सी # में एक प्रोग्राम लिखने की कल्पना करें । इसे पायथन या जावास्क्रिप्ट जैसी भाषाओं को "अनइंस्टैप्ड" कहना अधिक सटीक होगा। (यह दावा संभवतः कई लोगों को भ्रमित / परेशान करेगा, इस तरह के जावा या सी # कार्यक्रम पर विचार करने से कई उप-प्रकारों का उपयोग किया जाएगा, लेकिन ऐसा इसलिए है क्योंकि औसत ओओपी भाषा प्रकारों और कक्षाओं का सामना करती है। अधिक जानकारी के लिए ब्लॉग पोस्ट पढ़ें।)

ध्यान दें कि यहां तक ​​कि C में "डायनेमिक" टाइपिंग भी है - आप किसी भी पॉइंटर को a void(और यदि मैमोरी सर्व करते हैं, char) पॉइंटर को वापस कास्ट कर सकते हैं । और ध्यान दें, यह भी, कि वहाँ कोई रनटाइम जाँच नहीं है; यदि आपको यह गलत लगता है, तो अपने अपरिभाषित व्यवहार का आनंद लें!


लेकिन कास्ट को स्टैटिकली किया जाता है। मैं यह देखने में विफल हूं कि यह गतिशील टाइपिंग का उदाहरण कैसे है।
osa

@ क्योंकि कोड का कहना String foo = (String) barहै कि इसका मतलब यह नहीं है कि barवास्तव में एक है String। आप केवल यह जान सकते हैं कि रन टाइम में सुनिश्चित करने के लिए, इसलिए मैं यह नहीं देखता कि कलाकारों को "स्टैटिकली" कैसे किया जाता है।
डोभाल

मैं इससे सहमत नहीं हूं। कम से कम जावास्क्रिप्ट में, आप रनटाइम में ऑब्जेक्ट में नए तरीके और गुण जोड़ सकते हैं। C # में, आपको ऐसा करने के लिए किसी dynamicऑब्जेक्ट का स्पष्ट रूप से उपयोग करने की आवश्यकता है । यदि आप एक object... के लिए एक संपत्ति जोड़ने की कोशिश करते हैं , तो आप नहीं कर सकते।
आर्टुरो टॉरेस सांचेज़

3

स्थिर और गतिशील टाइपिंग के बीच का अंतर तब होता है जब किसी मान का प्रकार जांचा जाता है: संकलन समय बनाम रन समय। उन भाषाओं में जहां मान अपने प्रकार को अपने साथ ले जाते हैं (उदाहरण के लिए जावा ऑब्जेक्ट), तब आप हमेशा गतिशील टाइपिंग का सहारा ले सकते हैं, जब भाषा वास्तव में स्थिर टाइपिंग पसंद करती है। यहाँ जावा में एक उदाहरण है, एक गतिशील रूप से टाइप की गई विधि के साथ:

void horribleJava(List untypedList) {
  for (Object o : untypedList)
    ((SpecificType) o).frobnicate();
}

ध्यान दें कि प्रत्येक आइटम का प्रकार रनटाइम पर कैसे जांचा जाता है। समान रूप से टाइप की गई विधि है:

void goodJava(List<SpecificType> typedList) {
  for (SpecificType o : typedList) {
    o.forbnicate();
  }
}

सी में, मान (और विशेष रूप से संकेत) रनटाइम के दौरान अपने प्रकार को बरकरार नहीं रखते हैं - प्रत्येक सूचक एक के बराबर है void *। इसके बजाय, चर और अभिव्यक्ति का एक प्रकार है। डायनेमिक टाइपिंग को प्राप्त करने के लिए, आपको स्वयं जानकारी टाइप करनी होगी (जैसे कि एक स्ट्रक्चर में फ़ील्ड के रूप में)।


1
मुझे नहीं लगता कि कोई कास्ट वास्तव में व्यावहारिक अर्थों में गतिशील टाइपिंग के रूप में गिना जाता है। यह अभी भी संकलन-समय पर प्रकार के ज्ञान की आवश्यकता है, यह सिर्फ रनटाइम तक वास्तविक सत्यापन को रोकता है। आप frobnicateपहले के बारे में जानने के बिना यहां विधि का आह्वान नहीं कर सकते SpecificType
हारून ने

2
@Aaronaught लेकिन यह है गतिशील टाइपिंग एक बार हम समय को चलाने के लिए प्रकार की जांच स्थगित कर दिया है। ध्यान दें कि मेरे दोनों उदाहरण नाममात्र टाइपिंग का उपयोग करते हैं जिसके लिए एक विशिष्ट प्रकार के नाम की आवश्यकता होती है। आप संरचनात्मक टाइपिंग के बारे में सोच रहे हैं , उदाहरण के लिए बतख टाइपिंग जिसमें कुछ विधि की उपस्थिति की आवश्यकता होती है। अक्षीय संरचनात्मक बनाम नाममात्र और स्थिर बनाम गतिशील टाइपिंग एक दूसरे के लिए ऑर्थोगोनल हैं (जावा नाममात्र है और ज्यादातर स्थिर हैं; एमएल और गो संरचनात्मक और स्थिर हैं; पर्ल, पायथन और रूबी (ज्यादातर) संरचनात्मक और गतिशील हैं)।
आमोन

जैसा कि मैंने अपनी पिछली टिप्पणी में कहा, यह एक सैद्धांतिक अंतर है कि मैं जिस प्रोग्रामर से कभी नहीं मिला, उसकी वास्तव में परवाह है। आप स्पष्ट रूप से यह तर्क दे सकते हैं कि लोग गलत शब्दावली का उपयोग कर रहे हैं (और यह वास्तव में ऐसा प्रतीत होता है कि मूल ट्वीटर ठीक उस तरह के स्नार्कनेस के लिए जा रहा था) लेकिन ऐसे लोगों के लिए जो वास्तव में खाइयों में हैं, गतिशील टाइपिंग = बतख टाइपिंग। वास्तव में यह परिभाषा इतनी सामान्य है कि सी # जैसे शब्द वास्तव में इसे कोडित कर चुके हैं (यानी dynamicकीवर्ड के साथ )। Equating स्थिर करने के लिए संकलन समय और गतिशील करने के लिए क्रम ज्यादातर सिर्फ muddies पानी।
एरोनियक

@Aaronaught: यदि कोई एक इंटरफ़ेस को कास्ट करता है, और यदि क्लासेस जो कि एक विधि को इच्छित अर्थ के साथ लागू करता है, तो ऐसा कहने के लिए एक ही इंटरफ़ेस को लगातार कार्यान्वित करता है, तो एक अनिवार्य रूप से रन-टाइम डक-टाइपिंग होगा। हालांकि कुछ लोग यह तर्क दे सकते हैं कि "बतख टाइपिंग" को केवल विधि नाम का उपयोग करना चाहिए, मुझे लगता है कि इंटरफ़ेस नाम के साथ-साथ विधि नाम के रूप में "वास्तविक" विधि नाम के संबंध में अधिक उपयोगी होगा। अन्यथा, चाहिए [1,2].Add([3,4])उपज [1,2,3,4], [1,2,[3,4]]या [4,6]?
सुपरकैट

@ सुपरकैट: उपरोक्त में से कोई भी, यह विफल होना चाहिए क्योंकि Addसरणी पर कोई विधि नहीं है जो किसी सरणी को स्वीकार करता है क्योंकि ऐसी विधि अस्पष्ट होगी। बत्तख टाइपिंग आपको समझदार प्रकार और कार्यों को लिखने से नहीं रोकती है।
आरोनोन

2

स्टैटिक बनाम डायनामिक टाइपिंग मूल रूप से इस बात पर निर्भर करती है कि प्रकारों की जाँच कैसे की जाती है। स्टेटिक टाइपिंग का अर्थ है कि विभिन्न प्रकारों या अभिव्यक्तियों के प्रकारों का सत्यापन वास्तविक कोड (आमतौर पर कंपाइलर द्वारा) के आधार पर जांचा जाता है जबकि एक गतिशील प्रकार की प्रणाली में यह सत्यापन केवल रनटाइम वातावरण द्वारा, रनटाइम पर किया जाता है।

मेरा मानना ​​है कि पाठ का जिक्र है कि भले ही प्रकार वास्तव में सांख्यिकीय रूप से जांचे जाते हैं, फिर भी उन्हें रनटाइम पर जांचा जाता है, अर्थात गतिशील रूप से। आपने जावा रिफ्लेक्शन का सही उल्लेख किया है; प्रतिबिंब केवल रनटाइम पर होता है और जावा रनटाइम एनवायरनमेंट (JVM) वास्तव में प्रतिबिंब का उपयोग करने पर टाइप चेकिंग करता है, जिसका मूल अर्थ है डायनामिक टाइप चेकिंग।


तब यह सही नहीं है। सी ++ में, पास्कल, फोरट्रान --- किसी भी संकलित भाषाओं में --- प्रकार केवल सांख्यिकीय रूप से जांचे जाते हैं, और गतिशील रूप से नहीं (जब तक कि आप डायनेमिक_का उपयोग नहीं कर रहे हैं)। आप मेमोरी में मनमाने ढंग से सामान लिखने के लिए पॉइंटर्स का उपयोग कर सकते हैं, और किसी को भी प्रकार का पता नहीं चलेगा। तो स्थैतिक टाइपिंग का अर्थ केवल चेक स्टेटिक होता है, जबकि डायनेमिक टाइपिंग का मतलब केवल चेक पर होता है।
osa

-1

गलत होना गलत है: C में एक महत्वपूर्ण गतिशील प्रकार प्रणाली भी है। यह बस इसे चेक नहीं करता है ("सी दृढ़ता से टाइप किया गया है, कमजोर रूप से जांचा गया है")। उदाहरण के लिए, एक के रूप में एक struct के इलाज double( reinternpret_castएक गतिशील प्रकार की त्रुटि - शैली) अपरिभाषित व्यवहार अर्जित करता है।


(जिसने भी डाउनवोट किया - @ तेहियागो सिल्वा की टिप्पणी उसी बात के बारे में कहती है)
एलारज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.