डायनामिक टाइपिंग किस कार्यक्षमता की अनुमति देता है? [बन्द है]


91

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

लचीलेपन और पठनीयता जैसे गैर-कार्यात्मक मानदंडों के अलावा, गतिशील टाइपिंग चुनने के क्या कारण हैं? मैं गतिशील टाइपिंग के साथ क्या कर सकता हूं जो अन्यथा संभव नहीं है? आप किस विशिष्ट कोड उदाहरण के बारे में सोच सकते हैं जो डायनामिक टाइपिंग का एक ठोस लाभ दिखाता है?


5
सैद्धांतिक रूप से ऐसा कुछ भी नहीं है जिसे आप या तो नहीं कर सकते, जब तक कि भाषाएँ ट्यूरिंग कम्प्लीट नहीं होती हैं । मेरे लिए सबसे दिलचस्प सवाल यह है कि एक बनाम दूसरे में क्या आसान या स्वाभाविक है। मैं पायथन में नियमित रूप से कर रही चीजें हैं जो मैं सी ++ में भी विचार नहीं करूंगा, हालांकि मुझे पता है कि यह सक्षम है।
मार्क रैनसम

28
जैसा कि क्रिस स्मिथ अपने उत्कृष्ट निबंध में लिखते हैं कि डिबेटिंग टाइप सिस्टम से पहले क्या जानना चाहिए : "इस मामले में, समस्या यह है कि अधिकांश प्रोग्रामर को सीमित अनुभव है, और उन्होंने बहुत सारी भाषाओं की कोशिश नहीं की है। संदर्भ के लिए, यहां, छह या सात। "बहुत कुछ" के रूप में गिना नहीं जाता है ... इसके दो दिलचस्प परिणाम हैं: (1) कई प्रोग्रामर्स ने बहुत खराब स्टेट टाइप की हुई भाषाओं का इस्तेमाल किया है। (2) कई प्रोग्रामर ने डायनामिक टाइप की गई भाषाओं का बहुत खराब इस्तेमाल किया है। "
डैनियल Pryden

3
@suslik: यदि भाषा की प्राथमिकताओं में निरर्थक प्रकार हैं, तो बेशक आप प्रकारों के साथ निरर्थक बातें कर सकते हैं। स्थैतिक और गतिशील टाइपिंग के बीच अंतर से इसका कोई लेना-देना नहीं है।
जॉन पर्पडी

10
@CzarekTomczak: यह कुछ गतिशील रूप से टाइप की जाने वाली भाषाओं की एक विशेषता है, हाँ। लेकिन रनटाइम के दौरान एक सांख्यिकीय रूप से टाइप की जाने वाली भाषा संभव है। उदाहरण के लिए, दृश्य स्टूडियो आपको डी # कोड को फिर से लिखने की अनुमति देता है, जबकि आप डिबगर में एक ब्रेकप्वाइंट पर होते हैं, और यहां तक ​​कि नए बदलावों के साथ अपने कोड को फिर से चलाने के लिए निर्देश सूचक को भी रिवाइंड करते हैं। जैसा कि मैंने अपनी अन्य टिप्पणी में क्रिस स्मिथ को उद्धृत किया है: "कई प्रोग्रामर ने बहुत खराब सांख्यिकीय रूप से टाइप की गई भाषाओं का उपयोग किया है" - जो आप जानते हैं, उन सभी सांख्यिकीय रूप से टाइप की गई भाषाओं का न्याय नहीं करते हैं।
डैनियल प्रीडन

11
@WarrenP: आप इस बात पर जोर देते हैं कि "डायनेमिक टाइप सिस्टम अतिरिक्त क्रॉफ्ट की मात्रा को कम करता है जो मुझे टाइप करना है" - लेकिन फिर आप पायथन की C ++ से तुलना करते हैं। यह उचित तुलना नहीं है: बेशक सी ++ पायथन से अधिक क्रिया है, लेकिन ऐसा उनके प्रकार के सिस्टम में अंतर के कारण नहीं है, यह उनके व्याकरण में अंतर के कारण है। यदि आप अपने प्रोग्राम स्रोत में वर्णों की संख्या कम करना चाहते हैं, तो J या APL सीखें: मैं गारंटी देता हूं कि वे छोटे होंगे। एक अधिक उचित तुलना पायथन की तुलना हास्केल से की जाएगी। (रिकॉर्ड के लिए: मैं अजगर से प्यार करता हूं और इसे C ++ से अधिक पसंद करता हूं, लेकिन मुझे हास्केल और भी अधिक पसंद है।)
डैनियल प्राइडेन

जवाबों:


50

चूंकि आपने एक विशिष्ट उदाहरण के लिए कहा था, इसलिए मैं आपको एक देता हूं।

रॉब कॉनरी का मैसिव ORM कोड की 400 लाइन है। यह छोटा है क्योंकि रोब SQL टेबल को मैप करने में सक्षम है और SQL टेबल को मिरर करने के लिए बहुत सारे स्टैटिक प्रकारों की आवश्यकता के बिना ऑब्जेक्ट परिणाम प्रदान करता है। यह dynamicC # में डेटा प्रकार का उपयोग करके पूरा किया गया है। रॉब के वेब पेज में इस प्रक्रिया का विस्तार से वर्णन किया गया है, लेकिन यह स्पष्ट है कि, इस विशेष उपयोग के मामले में, कोड के संक्षिप्तता के लिए ज़िम्मेदार डायनामिक टाइपिंग बड़े हिस्से में है।

सैम केसर की डैपर के साथ तुलना करें , जो स्थैतिक प्रकारों का उपयोग करता है; SQLMapperअकेले वर्ग कोड के 3000 लाइनों है।

ध्यान दें कि सामान्य अस्वीकरण लागू होते हैं, और आपका लाभ भिन्न हो सकता है; डैपर के पास मैसिव की तुलना में अलग लक्ष्य हैं। मैं इसे केवल एक उदाहरण के रूप में इंगित करता हूं जो आप कोड की 400 लाइनों में कर सकते हैं जो संभवतः गतिशील टाइपिंग के बिना संभव नहीं होगा।


डायनामिक टाइपिंग आपको रनटाइम के लिए अपने प्रकार के निर्णयों को स्थगित करने की अनुमति देता है। बस इतना ही।

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

स्टैटिक प्रकार की भाषाओं के समर्थक बताते हैं कि कंपाइलर आपके कोड को संकलित समय पर "कोड की" पर्याप्त मात्रा में "एकल जाँच" कर सकता है। यह एक अच्छी बात है। ™

C # में dynamicकीवर्ड है, जो आपके बाकी कोड में स्थिर प्रकार की सुरक्षा के लाभों को खोए बिना रनटाइम के प्रकार के निर्णय को स्थगित करने की अनुमति देता है। टाइप इंफ़ेक्शन ( var) हमेशा स्पष्ट रूप से घोषित प्रकारों की आवश्यकता को हटाकर एक सांख्यिकीय-टाइप भाषा में लिखने के दर्द को समाप्त करता है।


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


22
यदि मैंने एक साथ दो संख्यात्मक तार जोड़े हैं, तो भी मुझे एक संख्यात्मक परिणाम की उम्मीद नहीं होगी।
पीडीआर

22
@ रॉबर्ट मैं आपके अधिकांश उत्तर से सहमत हूं। हालांकि, ध्यान दें कि संवादात्मक रीड-इवल-प्रिंट लूप्स जैसे कि स्काला और हास्केल के साथ सांख्यिकीय रूप से टाइप की गई भाषाएं हैं। यह हो सकता है कि सी # सिर्फ एक विशेष रूप से इंटरैक्टिव भाषा नहीं है।
एंड्रेस एफ।

14
मुझे एक हास्केल सीखना होगा।
रॉबर्ट हार्वे

7
@RobertHarvey: आप आश्चर्यचकित / प्रभावित हो सकते हैं F # के साथ यदि आपने पहले ही प्रयास नहीं किया है। आप सभी (संकलन-समय) प्रकार की सुरक्षा प्राप्त करते हैं जो आपको सामान्य रूप से एक .NET भाषा में मिलती है, सिवाय इसके कि आपको कभी-कभी कई प्रकार की घोषणा करनी होगी। F # में टाइप का इंफेक्शन C # में जो उपलब्ध है / काम करता है उससे आगे निकल जाता है। इसके अलावा: एंड्रेस और डैनियल क्या इशारा कर रहे हैं, एफ # इंटरएक्टिव विजुअल स्टूडियो का हिस्सा है ...
स्टीवन एवर्स

8
"आप एक साथ दो तार जोड़ने नहीं जा रहे हैं और एक संख्यात्मक उत्तर की उम्मीद करते हैं जब तक कि तार में संख्यात्मक डेटा न हो, और यदि वे नहीं करते हैं, तो आप अप्रत्याशित परिणाम प्राप्त करने जा रहे हैं" क्षमा करें, इसका डायनेमिक बनाम स्थिर टाइपिंग से कोई लेना-देना नहीं है , यह मजबूत बनाम कमजोर टाइपिंग है।
वार्टेक

26

वाक्यांश "स्टैटिक टाइपिंग" और "डायनेमिक टाइपिंग" जैसे शब्द बहुत अधिक हैं, और लोग आसानी से अलग-अलग परिभाषाओं का उपयोग करते हैं, तो चलिए स्पष्ट करते हैं कि हमारा क्या मतलब है।

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

लेकिन अधिकांश स्टैटिक टाइप सिस्टम इस तरह का व्यवहार नहीं करते हैं। स्थैतिक प्रकार प्रणालियों के दो सामान्य गुण हैं जो सीमाएं लगा सकते हैं:

कंपाइलर एक प्रोग्राम को अस्वीकार कर सकता है जिसमें एक स्थिर प्रकार की त्रुटि होती है।

यह एक सीमा है क्योंकि कई प्रकार के सुरक्षित कार्यक्रमों में आवश्यक रूप से एक स्थिर प्रकार की त्रुटि होती है।

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

if sys.version_info[0] == 2:
    wfile.write(txt)
else:
    wfile.write(bytes(txt, 'utf-8'))

एक पायथन 2 स्टैटिक टाइप चेकर पायथन 3 कोड (और इसके विपरीत) को अस्वीकार कर देगा, भले ही इसे कभी भी निष्पादित नहीं किया जाएगा। मेरे प्रकार के सुरक्षित कार्यक्रम में एक स्थिर प्रकार की त्रुटि है।

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

स्टेटिक प्रकार की जाँच यह मानती है कि संकलित समय सूचना द्वारा रनटाइम वातावरण को पर्याप्त रूप से वर्णित किया गया है। लेकिन भविष्य की भविष्यवाणी खतरनाक है!

यहाँ एक और सीमा है:

संकलक कोड उत्पन्न कर सकता है जो मानता है कि रनटाइम प्रकार स्थिर प्रकार है।

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

एक्शन में इस तरह के रीमोटिंग के उदाहरणों में ओबीजीसी के एनएसएक्सपीसीसीऑक्शन या सी # ट्रांसपेरेंटप्रॉक्सी शामिल हैं (जिनके कार्यान्वयन के लिए रनटाइम में कुछ निराशा की आवश्यकता होती है - एक चर्चा के लिए यहां देखें )।

जब कोडजन स्थिर प्रकारों पर निर्भर नहीं होता है, और आपके पास संदेश अग्रेषण जैसी सुविधाएं होती हैं, तो आप प्रॉक्सी वस्तुओं, डिबगिंग, आदि के साथ बहुत सारे शांत सामान कर सकते हैं।

तो अगर आप एक प्रकार के चेकर को संतुष्ट करने के लिए आवश्यक नहीं हैं, तो आप कुछ सामानों का नमूना ले सकते हैं। सीमाएं स्थैतिक प्रकारों द्वारा नहीं लगाई जाती हैं, लेकिन लागू स्थैतिक प्रकार की जाँच द्वारा।


2
"एक पायथन 2 स्टैटिक टाइप चेकर पायथन 3 कोड (और इसके विपरीत) को अस्वीकार कर देगा, भले ही इसे कभी भी निष्पादित नहीं किया जाएगा। मेरे प्रकार के सुरक्षित प्रोग्राम में एक स्थिर प्रकार की त्रुटि है।" लगता है कि आपको वास्तव में किस तरह की ज़रूरत है "स्थिर अगर", जहां संकलक / दुभाषिया कोड को देख भी नहीं सकता है यदि स्थिति झूठी है।
डेविड स्टोन

@davidstone जो c ++ में मौजूद है
मिलिंद R

A Python 2 static type checker would reject the Python 3 code (and vice versa), even though it would never be executed. My type safe program contains a static type error. किसी भी उचित स्थिर भाषा में, आप IFDEFदोनों मामलों में प्रकार की सुरक्षा बनाए रखते हुए, एक प्रकार के प्रीप्रोसेसर स्टेटमेंट के साथ ऐसा कर सकते हैं ।
मेसन व्हीलर

1
@MasonWheeler, davidstone नहीं, प्रीप्रोसेसर चालें और static_if दोनों बहुत स्थिर हैं। मेरे उदाहरण में मैंने Python2 और Python3 का उपयोग किया है, लेकिन यह AmazingModule2.0 और AmazingModule3.0 के रूप में आसानी से हो सकता है, जहां कुछ इंटरफ़ेस संस्करणों के बीच बदल गए। सबसे पहले आप जिस इंटरफ़ेस को जान सकते हैं वह मॉड्यूल आयात समय पर है, जो आवश्यक रूप से रनटाइम पर है (कम से कम अगर आपको गतिशील लिंकिंग का समर्थन करने की कोई इच्छा है)।
हास्यास्पद_फिश

18

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

लेकिन गतिशील रूप से बनाए गए संग्रह में बतख टाइपिंग किसी अन्य तरीके से प्राप्त करना कठिन है:

>>> d = JSON.parse(foo)
>>> d['bar'][3]
12
>>> d['baz']['qux']
'quux'

तो, किस प्रकार की JSON.parseवापसी होती है? सरणियों का एक शब्दकोश-पूर्णांक या शब्दकोशों-ऑफ-स्ट्रिंग्स? नहीं, यह भी सामान्य नहीं है।

JSON.parseकिसी प्रकार के "वैरिएंट वैल्यू" को वापस करना होता है, जो इन प्रकारों में से किसी भी प्रकार से अशक्त, बूल, फ्लोट, स्ट्रिंग, या किसी भी प्रकार के स्ट्रिंग से शब्दकोश में पुनरावर्ती हो सकता है। डायनामिक टाइपिंग की मुख्य ताकत ऐसे वेरिएंट प्रकार के होते हैं।

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

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


21
आपका JSON पार्सिंग उदाहरण आसानी से एक बीजीय डेटा प्रकार द्वारा सांख्यिकीय रूप से नियंत्रित किया जा सकता है ।

2
ठीक है, मेरा उत्तर पर्याप्त नहीं था; धन्यवाद। वह JSValue एक गतिशील प्रकार की एक स्पष्ट परिभाषा है, बिल्कुल वही जो मैं बात कर रहा था। यह उन गतिशील प्रकार हैं जो उपयोगी हैं, न कि ऐसी भाषाएं जिन्हें गतिशील टाइपिंग की आवश्यकता होती है। हालांकि, यह अभी भी प्रासंगिक है कि गतिशील प्रकार स्वचालित रूप से किसी भी वास्तविक प्रकार की अनुमान प्रणाली द्वारा उत्पन्न नहीं किया जा सकता है, जबकि अधिकांश सामान्य उदाहरण लोग तुच्छ रूप से अप्राकृतिक हैं। मुझे उम्मीद है कि नया संस्करण इसे बेहतर तरीके से समझाएगा।
23

4
@MattFenwick बीजगणितीय डेटा प्रकार बहुत कार्यात्मक भाषाओं (व्यवहार में) तक सीमित हैं। जावा और c # जैसी भाषाओं के बारे में क्या?
spirc

4
एडीटी सी / सी ++ में टैग यूनियनों के रूप में मौजूद हैं। यह कार्यात्मक भाषाओं के लिए अद्वितीय नहीं है।
क्लार्क गैबेल

2
@spirc आप कई वर्गों का उपयोग करके एक शास्त्रीय OO भाषा में ADTs का अनुकरण कर सकते हैं जो सभी एक सामान्य इंटरफ़ेस से प्राप्त होते हैं, getClass () या GetType (), और समानता जांच के लिए रन-टाइम कॉल करते हैं। या आप दोहरे प्रेषण का उपयोग कर सकते हैं, लेकिन मुझे लगता है कि सी ++ में अधिक भुगतान करता है। तो आपके पास एक JSObject इंटरफ़ेस, और JSString, JSNumber, JSHash और JSArray कक्षाएं हो सकती हैं। फिर आपको "एप्लिकेशन टाइप किए गए" डेटा संरचना में इस "अनकैप्ड" डेटा संरचना को चालू करने के लिए कुछ कोड की आवश्यकता होगी। लेकिन आप शायद ऐसा डायनामिक-टाइप की हुई भाषा में भी करना चाहेंगे।
डैनियल यांकोव्स्की

12

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

मैं एक उदाहरण दूंगा। मान लीजिए कि आप डेटा ऑब्जेक्ट्स, उनके संग्रह आदि का वर्णन करने के लिए एक साधारण डेटा मॉडल लागू करते हैं, जो कि इस अर्थ में सांख्यिकीय रूप से टाइप किया जाता है कि, यदि मॉडल कहता है कि xफू की वस्तु की विशेषता पूर्णांक रखती है, तो उसे हमेशा पूर्णांक रखना चाहिए। क्योंकि यह एक रनटाइम कंस्ट्रक्शन है, आप इसे स्टेटिकली टाइप नहीं कर सकते। मान लीजिए कि आप YAML फ़ाइलों में वर्णित डेटा संग्रहीत करते हैं। आप एक हैश मैप बनाते हैं (बाद में एक YAML लाइब्रेरी को सौंपने के लिए), xविशेषता प्राप्त करें , इसे मैप में स्टोर करें, अन्य विशेषता प्राप्त करें जो कि स्ट्रिंग होने के लिए बस इतना होता है, ... एक सेकंड पकड़ो? the_map[some_key]अब का प्रकार क्या है ? अच्छी तरह से गोली मार, हम जानते हैं कि परिणाम some_keyहै 'x'और इसलिए एक पूर्णांक होना चाहिए, लेकिन प्रकार प्रणाली भी इस बारे में कारण शुरू नहीं कर सकते हैं।

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

बेशक, आज का समाधान सब कुछ बॉक्सिंग है और फिर कास्टिंग (या ओवरराइड विधियों का एक गुच्छा है, जिनमें से अधिकांश "अपवादों को लागू नहीं" करते हैं)। लेकिन यह वैधानिक रूप से टाइप नहीं किया गया है, यह रनटाइम पर टाइप चेक करने के लिए टाइप सिस्टम के आसपास एक हैक है।


सामान्य प्रकारों में मुक्केबाजी की आवश्यकता नहीं होती है।
रॉबर्ट हार्वे

@ रोबर्टहेरवे हाँ। मैं बात नहीं कर रहा था में जावा सी # मुक्केबाजी, मैं "कुछ आवरण वर्ग जिनका एकमात्र उद्देश्य यू की एक उप-प्रकार में टी के मूल्य का प्रतिनिधित्व कर रहा है में यह लपेट" के बारे में बात कर रहा था। पैरामीट्रिक पॉलीमॉर्फिज्म (जिसे आप जेनेरिक टाइपिंग कहते हैं) हालांकि मेरे उदाहरण पर लागू नहीं होता है। यह ठोस प्रकारों पर एक संकलन-समय का अमूर्त है, लेकिन हमें एक रनटाइम टाइपिंग तंत्र की आवश्यकता है।

यह इंगित करने के लायक हो सकता है कि स्काला की प्रकार की प्रणाली ट्यूरिंग पूर्ण है। तो टाइप सिस्टम आपके चित्र से कम तुच्छ हो सकते हैं।
एंड्रिया

@ और जानबूझकर मैंने पूर्णता को छेड़ने के लिए अपने विवरण को कम नहीं किया। कभी ट्यूरिंग टारपीट में प्रोग्राम किया है? या इन चीजों को प्रकारों में एनकोड करने की कोशिश की? कुछ बिंदु पर, संभव होने के लिए यह बहुत जटिल हो जाता है।

@delnan मैं सहमत हूँ। मैं सिर्फ इशारा कर रहा था कि टाइप सिस्टम काफी जटिल चीजें कर सकते हैं। मुझे आभास था कि आपके उत्तर का मतलब यह है कि टाइप सिस्टम केवल तुच्छ सत्यापन कर सकता है, लेकिन दूसरी बार पढ़ने पर आपने ऐसा कुछ नहीं लिखा!
एंड्रिया

7

डायनेमिक टाइपिंग के साथ ऐसा कुछ भी नहीं है जिसे आप स्टैटिक टाइपिंग के साथ नहीं कर सकते, क्योंकि आप एक स्टेटिक टाइप की गई भाषा के ऊपर डायनामिक टाइपिंग को लागू कर सकते हैं।

हास्केल में एक छोटा उदाहरण:

data Data = DString String | DInt Int | DDouble Double

-- defining a '+' operator here, with explicit promotion behavior
DString a + DString b = DString (a ++ b)
DString a + DInt b = DString (a ++ show b)
DString a + DDouble b = DString (a ++ show b)
DInt a + DString b = DString (show a ++ b)
DInt a + DInt b = DInt (a + b)
DInt a + DDouble b = DDouble (fromIntegral a + b)
DDouble a + DString b = DString (show a ++ b)
DDouble a + DInt b = DDouble (a + fromIntegral b)
DDouble a + DDouble b = DDouble (a + b)

पर्याप्त मामलों के साथ आप किसी भी गतिशील प्रकार की प्रणाली को लागू कर सकते हैं।

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

संपादित करें: मैं इसे सरल रखना चाहता था, लेकिन यहां एक वस्तु मॉडल के बारे में अधिक विवरण हैं

एक फ़ंक्शन तर्कों के रूप में डेटा की एक सूची लेता है और ImplMonad में साइड इफेक्ट्स के साथ गणना करता है, और एक डेटा लौटाता है।

type Function = [Data] -> ImplMonad Data

DMember या तो एक सदस्य मूल्य या एक समारोह है।

data DMember = DMemValue Data | DMemFunction Function

Dataवस्तुओं और कार्यों को शामिल करने के लिए विस्तार करें । ऑब्जेक्ट नामित सदस्यों की सूची हैं।

data Data = .... | DObject [(String, DMember)] | DFunction Function

ये स्थिर प्रकार हर गतिशील रूप से टाइप किए गए ऑब्जेक्ट सिस्टम को लागू करने के लिए पर्याप्त हैं, जिनसे मैं परिचित हूं।


यह बिल्कुल भी समान नहीं है क्योंकि आप परिभाषा को फिर से बताए बिना नए प्रकार नहीं जोड़ सकते Data
जेड

5
आप अपने उदाहरण में कमजोर टाइपिंग के साथ गतिशील टाइपिंग की अवधारणाओं को मिला रहे हैं। डायनामिक टाइपिंग अज्ञात प्रकारों के संचालन के बारे में है, अनुमत प्रकारों की सूची को परिभाषित नहीं करना और उन दोनों के बीच संचालन को ओवरलोड करना है।
hcalves

2
@Jed एक बार जब आप ऑब्जेक्ट मॉडल, मौलिक प्रकार, और आदिम संचालन को लागू कर लेते हैं, तो कोई अन्य आधार आवश्यक नहीं है। आप मूल डायनेमिक भाषा में इस बोली में आसानी से और स्वचालित रूप से कार्यक्रमों का अनुवाद कर सकते हैं।
नोवाडेनजेन ऑक्ट

2
@ जब से आप मेरे हास्केल कोड में ओवरलोडिंग का जिक्र कर रहे हैं मुझे संदेह है कि आपके पास इसके शब्दार्थ के बारे में सही विचार नहीं है। वहाँ मैंने एक नए +ऑपरेटर को परिभाषित किया है जो दो Dataमानों को दूसरे Dataमूल्य में जोड़ता है । Dataगतिशील प्रकार प्रणाली में मानक मूल्यों का प्रतिनिधित्व करता है।
नोवाडेनिज़न

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

3

झिल्ली :

एक झिल्ली पूरे ऑब्जेक्ट ग्राफ के चारों ओर एक आवरण है, जैसा कि केवल एक ही वस्तु के लिए आवरण के विपरीत है। आमतौर पर, एक झिल्ली का निर्माता झिल्ली में सिर्फ एक ही वस्तु को लपेटता है। मुख्य विचार यह है कि झिल्ली को पार करने वाला कोई भी वस्तु संदर्भ स्वयं ही एक ही झिल्ली में लिपटा हुआ होता है।

यहाँ छवि विवरण दर्ज करें

प्रत्येक प्रकार को एक प्रकार से लपेटा जाता है, जिसमें एक ही इंटरफ़ेस होता है, लेकिन जो संदेशों और आवरणों को अपरिवर्तित करते हैं और मानों को अपरिवर्तित करते हैं क्योंकि वे झिल्ली को पार करते हैं। आपकी पसंदीदा सांख्यिकीय रूप से टाइप की गई भाषा में रैप फ़ंक्शन का प्रकार क्या है? हो सकता है कि हास्केल के पास उस फ़ंक्शन के लिए एक प्रकार है, लेकिन अधिकांश सांख्यिकीय रूप से टाइप की गई भाषाएं ऑब्जेक्ट → ऑब्जेक्ट का उपयोग करके समाप्त नहीं होती हैं, प्रभावी ढंग से टाइप-चेकर्स के रूप में उनकी जिम्मेदारी का सामना करती हैं।


4
हाँ, हास्केल वास्तव में अस्तित्वगत प्रकारों का उपयोग कर सकता है। यदि आपके पास कुछ प्रकार वर्ग फू है, तो आप उस इंटरफ़ेस को किसी भी प्रकार के इंस्टेंट करने के आसपास एक आवरण बना सकते हैं। class Foo a where ... data Wrapper = forall a. Foo a => Wrapper a
जेक मैकआर्थर

@JakeMcArthur, समझाने के लिए धन्यवाद। यही कारण है कि मेरे पास बैठकर हास्केल सीखने का एक और कारण है।
माइक शमूएल

2
आपकी झिल्ली एक 'इंटरफ़ेस' है और ऑब्जेक्ट्स के प्रकार "अस्तित्वगत रूप से टाइप किए गए" हैं - अर्थात, हम जानते हैं कि वे इंटरफ़ेस के नीचे मौजूद हैं, लेकिन यह हम सभी जानते हैं। 80 के दशक के बाद से डेटा अमूर्त के लिए संभावित प्रकार ज्ञात किया गया है। एक अच्छा रेफरी है cs.cmu.edu/~rwh/plbook/book.pdf चैप्टर 21.1
डॉन स्टीवर्ट

@DonStewart। क्या जावा प्रॉक्सी कक्षाएं एक अस्तित्व प्रकार का तंत्र हैं? एक जगह जहां झिल्ली मुश्किल हो जाती है, नाममात्र प्रकार की प्रणालियों वाली भाषाओं में होती है, जिसमें उस प्रकार की परिभाषा के बाहर दिखाई देने वाले कंक्रीट प्रकार के नाम होते हैं। उदाहरण के लिए, कोई Stringजावा में एक ठोस प्रकार होने के कारण इसे लपेट नहीं सकता है। स्मॉलटाक को यह समस्या नहीं है क्योंकि यह टाइप करने का प्रयास नहीं करता है #doesNotUnderstand
माइक शमूएल

1

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

बेहतर सवाल यह है कि डायनामिक टाइपिंग कुछ स्थितियों और समस्याओं में अधिक उपयुक्त और अधिक उपयुक्त क्यों है।

सबसे पहले, परिभाषित करने देता है

इकाई - मुझे कोड में कुछ इकाई की सामान्य धारणा की आवश्यकता होगी। यह आदिम संख्या से जटिल डेटा तक कुछ भी हो सकता है।

व्यवहार - मान लें कि हमारी इकाई में कुछ अवस्थाएँ और विधियाँ हैं जो बाहरी दुनिया को कुछ प्रतिक्रियाओं के लिए इकाई को निर्देश देने की अनुमति देती हैं। इस इकाई के राज्य + इंटरफ़ेस को इसके व्यवहार को कहते हैं। एक इकाई उपकरण भाषा प्रदान करता है द्वारा एक निश्चित तरीके से संयुक्त एक से अधिक व्यवहार हो सकता है

संस्थाओं और उनके व्यवहारों की परिभाषाएँ - हर भाषा कुछ सार तत्व प्रदान करती है जो आपको कार्यक्रम में कुछ संस्थाओं के व्यवहार (तरीकों + आंतरिक स्थिति) को परिभाषित करने में मदद करती है। आप इन व्यवहारों के लिए एक नाम निर्दिष्ट कर सकते हैं और कह सकते हैं कि इस व्यवहार के सभी उदाहरण निश्चित प्रकार के हैं

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

स्टैटिक टाइपिंग - आपके प्रोग्राम की सभी संस्थाओं के व्यवहार की जांच संकलन समय से पहले शुरू हो जाती है। इसका मतलब यह है कि यदि आप उदाहरण के लिए अपने व्यक्ति की इकाई को व्यवहार (जैसे व्यवहार करने के लिए) चाहते हैं, तो आपको इकाई जादूगर जादूगर को परिभाषित करना होगा और इसे फेंकने वाले जैसे जादूगर का व्यवहार देना होगा ()। यदि आप अपने कोड में, गलती से साधारण व्यक्ति को बताएं। दुखद (दुखद) संकलक आपको बताएगा"Error >>> hell, this Person has no this behavior, dunno throwing magics, no run!".

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

अधिकांश डायनामिक टाइपिंग भाषाओं में एक सामान्य व्यवहार प्रदान करने के लिए तंत्र होते हैं जो किसी भी संदेश को पकड़ेंगे जो उनके इंटरफ़ेस पर जाता है। उदाहरण के लिए रूबी method_missingऔर PHP __callअगर मुझे अच्छी याद है। इसका मतलब है कि आप कार्यक्रम के समय में किसी भी प्रकार की दिलचस्प चीजें कर सकते हैं और वर्तमान कार्यक्रम की स्थिति के आधार पर प्रकार का निर्णय ले सकते हैं। यह एक समस्या के मॉडलिंग के लिए उपकरण लाता है जो जावा की तुलना में बहुत अधिक लचीले होते हैं, जो कहते हैं, रूढ़िवादी स्थिर प्रोग्रामिंग भाषा।

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