स्थैतिक टाइपिंग वास्तव में बड़ी परियोजनाओं में कैसे सहायक है?


9

स्क्रिप्टिंग प्रोग्रामिंग भाषा की साइट के मुख्य पृष्ठ पर क्यूरिंग करते समय, मुझे इस मार्ग का सामना करना पड़ा:

जब एक प्रणाली आपके सिर में रखने के लिए बहुत बड़ी हो जाती है, तो आप स्थैतिक प्रकार जोड़ सकते हैं।

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

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

इसके अलावा, जैसे ही फ़ंक्शंस घोषित किए जाते हैं type funcname()..., typeआपको यह जानकर वाइटआउट करना होगा कि प्रत्येक पंक्ति में उस फ़ंक्शन को खोजना होगा, जिसमें फ़ंक्शन को कहा जाता है, क्योंकि आप केवल जानते हैं funcname, जबकि पायथन में और जैसे आप बस के लिए खोज करते हैं def funcnameया function funcnameजो केवल एक बार होता है, पर घोषणा।

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

तो, एक फ़ंक्शन के रिटर्न प्रकार को जानने के अलावा, जो स्पष्ट रूप से स्थैतिक रूप से टाइप की गई भाषाओं का एक कड़ा बिंदु नहीं है, स्थैतिक टाइपिंग वास्तव में बड़ी परियोजनाओं में कैसे सहायक है?



2
यदि आप अन्य प्रश्न के उत्तर पढ़ते हैं, तो आपको संभवतः इस एक के लिए आवश्यक उत्तर मिलेंगे, वे मूल रूप से अलग-अलग दृष्टिकोणों से एक ही बात पूछ रहे हैं :)
सारा

1
स्विफ्ट और खेल के मैदान एक सांख्यिकीय रूप से टाइप की जाने वाली भाषा का एक REPL हैं।
daven11

2
भाषाएं संकलित नहीं हैं, कार्यान्वयन हैं। एक "संकलित" भाषा के लिए एक REPL लिखने का तरीका कुछ ऐसा लिखना है जो भाषा की व्याख्या कर सकता है, या कम से कम संकलित कर सकता है और आवश्यक स्थिति को ध्यान में रखते हुए लाइन द्वारा निष्पादित कर सकता है। इसके अलावा, जावा 9 एक आरईपीएल के साथ जहाज जाएगा।
सेबेस्टियन रेडल

2
@ user6245072: यहां बताया गया है कि इंटरप्रेटर के लिए एक REPL कैसे बनाया जाता है: कोड पढ़ें, दुभाषिया को भेजें, परिणाम का प्रिंट आउट लें। यहां कंपाइलर के लिए एक REPL कैसे बनाया जाता है: कोड पढ़ें, इसे कंपाइलर को भेजें, संकलित कोड चलाएं , परिणाम प्रिंट करें। बहुत आसान। ठीक यही एफएसआई (एफई आरईपीएल), जीएचसीआई (जीएचसी हास्केल का आरईपीएल), स्काला आरईपीएल और क्लिंग करते हैं।
जर्ग डब्ल्यू मित्तग

जवाबों:


21

अधिक से अधिक, REPLs के साथ यह विभिन्न प्रकार के इनपुट के साथ वापसी प्रकार के लिए एक फ़ंक्शन का परीक्षण करने के लिए तुच्छ है

यह तुच्छ नहीं है। यह तुच्छ नहीं है सब पर । तुच्छ कार्यों के लिए ऐसा करना केवल तुच्छ है।

उदाहरण के लिए, आप तुच्छ रूप से एक फ़ंक्शन को परिभाषित कर सकते हैं जहां रिटर्न प्रकार पूरी तरह से इनपुट प्रकार पर निर्भर करता है।

getAnswer(v) {
 return v.answer
}

इस मामले में, getAnswerवास्तव में एक भी वापसी प्रकार नहीं है। कोई परीक्षण नहीं है जो आप कभी भी लिख सकते हैं कि यह एक नमूना इनपुट के साथ कॉल करता है यह जानने के लिए कि रिटर्न प्रकार क्या है। यह हमेशा वास्तविक तर्क पर निर्भर करेगा । चलने के समय पर।

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

getAnswer(x, y) {
   if (x + y.answer == 13)
       return 1;
   return "1";
}

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

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

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

स्मृति से, def funcnameपायथन में पर्याप्त नहीं होगा, क्योंकि समारोह को फिर से मनमाने ढंग से सौंपा जा सकता है। या कई मॉड्यूल में बार-बार घोषित किया जा सकता है। या कक्षाओं में। आदि।

और आपको अभी भी उस पंक्ति पर वापस लौटना होगा जिसमें इसे जाँचने के लिए आपके पाठ संपादक के खोज फ़ंक्शन का उपयोग करके घोषित किया गया है।

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


2
निष्पक्ष होने के लिए, उन "टूल" का आविष्कार गतिशील भाषाओं में किया गया था, और गतिशील भाषाओं ने उन्हें स्थिर भाषाओं के बहुत पहले किया था। डेफिनिशन, कोड कंप्लीशन, ऑटोमैटिक रिफैक्टिंग आदि पर जाएं, ग्राफिकल लिस्प और स्मालटाक आईडीई में मौजूद थे, जबकि स्टैटिक भाषाओं में भी ग्राफिक्स या आईडीई थे, अकेले ग्राफिकल आईडीई करें।
जोर्ग डब्ल्यू मित्तग

कार्यों की वापसी प्रकार को जानने का हमेशा तुम्हें नहीं बताता कार्यों क्या करते हैं । लेखन प्रकारों के बजाय आप नमूना मूल्यों के साथ डॉक्टर परीक्षण लिख सकते थे। उदाहरण के लिए, तुलना करें (शब्द 'कुछ शब्द' कहां ') => [' कुछ ',' शब्द ',' ऊऊ '] के साथ (शब्द स्ट्रिंग) -> [स्ट्रिंग], (ज़िप {abc} [1..3]) => [(ए, 1), (बी, 2), (सी, 3)] इसके प्रकार के साथ।
aoeu256

18

कई प्रोग्रामर्स के साथ एक प्रोजेक्ट के बारे में सोचें, जो वर्षों में बदल गया है। आपको इसे बनाए रखना होगा। एक समारोह है

getAnswer(v) {
 return v.answer
}

पृथ्वी पर यह क्या करता है? क्या है v? तत्व कहां answerसे आता है?

getAnswer(v : AnswerBot) {
  return v.answer
}

अब हमारे पास कुछ और जानकारी है -; इसे एक प्रकार की आवश्यकता है AnswerBot

यदि हम एक वर्ग-आधारित भाषा पर जाएं तो हम कह सकते हैं

class AnswerBot {
  var answer : String
  func getAnswer() -> String {
    return answer
  }
}

अब हमारे पास एक प्रकार का चर हो सकता है AnswerBotऔर विधि को कॉल कर सकते हैं getAnswerऔर हर कोई जानता है कि यह क्या करता है। किसी भी रनटाइम टेस्टिंग से पहले किसी भी बदलाव को कंपाइलर द्वारा पकड़ा जाता है। कई अन्य उदाहरण हैं लेकिन शायद यह आपको विचार देता है?


1
पहले से ही स्पष्ट लग रहा है - जब तक आप इंगित नहीं करते हैं कि इस तरह के एक समारोह में मौजूद होने का कोई कारण नहीं है, बू यह सिर्फ एक उदाहरण है।
user6245072

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

1
मुझे लगता है कि यह कार्यात्मक प्रोग्रामिंग की गलतफहमी है जो इसका कारण बनती है। हालाँकि, वैश्विक नाम स्थान में आपके कहने का क्या मतलब है?
user6245072

3
"गतिशील भाषाओं में फ़ंक्शन वैश्विक नामस्थान में डिफ़ॉल्ट रूप से हैं" यह एक भाषा विशिष्ट विवरण है, और गतिशील टाइपिंग के कारण बाधा नहीं है।
सारा

2
@ daven11 "मैं यहाँ जावास्क्रिप्ट सोच रहा हूँ", वास्तव में, लेकिन अन्य गतिशील भाषाओं में वास्तविक नामस्थान / मॉड्यूल / पैकेज हैं और ये आपको पुन: परिभाषित करने पर चेतावनी दे सकते हैं। आप कुछ हद तक सामान्य हो सकते हैं।
coredump

10

आपको लगता है कि बड़ी स्थिर परियोजनाओं के साथ काम करने के बारे में कुछ गलत धारणाएं हैं जो आपके निर्णय पर धब्बा लगा सकती हैं। यहाँ कुछ संकेत दिए गए हैं:

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

सांख्यिकीय रूप से टाइप की गई भाषाओं के साथ काम करने वाले अधिकांश लोग या तो भाषा के लिए एक IDE या एक बुद्धिमान संपादक (जैसे vim या emacs) का उपयोग करते हैं, जिनका भाषा-विशिष्ट उपकरणों के साथ एकीकरण होता है। इन उपकरणों में फ़ंक्शन के प्रकार को खोजने का एक तेज़ तरीका है। उदाहरण के लिए, एक जावा प्रोजेक्ट पर ग्रहण के साथ, दो तरीके हैं जो आप आमतौर पर एक विधि का प्रकार पाएंगे:

  • अगर मैं 'ए' की तुलना में किसी अन्य ऑब्जेक्ट पर एक विधि का उपयोग करना चाहता हूं, तो मैं एक संदर्भ टाइप करता हूं और एक डॉट (जैसे someVariable.) और ग्रहण के प्रकार को देखता है someVariableऔर उस प्रकार में परिभाषित सभी विधियों की एक ड्रॉप डाउन सूची प्रदान करता है; जैसा कि मैंने सूची को नीचे स्क्रॉल किया है और चयनित होने के दौरान प्रत्येक का प्रकार और प्रलेखन प्रदर्शित होता है। ध्यान दें कि गतिशील भाषा के साथ इसे प्राप्त करना बहुत कठिन है, क्योंकि संपादक के लिए यह कठिन है (या कुछ मामलों में असंभव है) यह निर्धारित करने के लिए कि प्रकार क्या someVariableहै, इसलिए यह आसानी से सही सूची उत्पन्न नहीं कर सकता है। यदि मैं एक विधि का उपयोग करना चाहता हूं तो मैं एक thisही सूची प्राप्त करने के लिए ctrl + स्पेस दबा सकता हूं (हालांकि इस मामले में यह गतिशील भाषाओं के लिए प्राप्त करना कठिन नहीं है)।
  • यदि मेरे पास पहले से ही एक विशिष्ट विधि के लिए लिखा गया संदर्भ है, तो मैं उस पर माउस कर्सर को स्थानांतरित कर सकता हूं और विधि के लिए प्रकार और प्रलेखन टूलटिप में प्रदर्शित होता है।

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

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

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

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

अधिक से अधिक, REPLs के साथ यह विभिन्न प्रकार के इनपुट के साथ वापसी प्रकार के लिए एक फ़ंक्शन का परीक्षण करने के लिए तुच्छ है

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

स्थैतिक रूप से टाइप की गई भाषाओं के साथ आपको कोड की कुछ पंक्तियाँ जोड़ने और घोषित प्रकार जानने के लिए सब कुछ फिर से जोड़ने की आवश्यकता होगी।

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


4
You seem to have a few misconceptions about working with large static projects that may be clouding your judgement.ठीक है, मैं केवल 14 साल का हूं और मैं केवल एंड्रॉइड पर एक वर्ष से कम समय से कार्यक्रम करता हूं, इसलिए यह संभव है कि मुझे लगता है।
उपयोगकर्ता 6245072

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

6
  1. क्योंकि स्टेटिक चेकर्स स्टैटिकली टाइप की गई भाषाओं के लिए आसान होते हैं।
    • नंगे न्यूनतम पर, कोई गतिशील भाषा सुविधाओं के साथ, यदि यह संकलित करता है, तो रनटाइम पर कोई अनसुलझे कार्य नहीं होते हैं। यह एडीए परियोजनाओं और सी में माइक्रोकंट्रोलर पर आम है। (माइक्रोकंट्रोलर प्रोग्राम कभी-कभी बड़े हो जाते हैं ... जैसे सैकड़ों kloc बड़े।)
  2. स्टेटिक कंपाइल रेफरेंस चेक फंक्शन इन्वर्टिस का एक सबसेट होता है, जिसे स्टैटिक लैंग्वेज में कंपाइल-टाइम पर भी चेक किया जा सकता है।
  3. स्थैतिक भाषाओं में आमतौर पर अधिक संदर्भात्मक पारदर्शिता होती है। इसका परिणाम यह है कि एक नया डेवलपर एकल फ़ाइल में गोता लगा सकता है और जो कुछ चल रहा है उसे समझ सकता है, और बग को ठीक कर सकता है या कोडबेस की सभी अजीब चीजों को जाने बिना एक छोटी सी सुविधा जोड़ सकता है।

कहना, जावास्क्रिप्ट, रूबी या स्मालटाक के साथ तुलना करें, जहां डेवलपर्स रन समय पर कोर भाषा की कार्यक्षमता को फिर से परिभाषित करते हैं। इससे बड़े प्रॉजेक्ट को समझना मुश्किल हो जाता है।

बड़ी परियोजनाओं में अधिक लोग नहीं होते हैं, उनके पास अधिक समय होता है। हर किसी को भूलने, या आगे बढ़ने के लिए पर्याप्त समय।

वास्तविक रूप से, मेरे एक परिचित के पास लिस्प में एक सुरक्षित "नौकरी के लिए जीवन" प्रोग्रामिंग है। टीम को छोड़कर कोई भी कोड-बेस को नहीं समझ सकता है।


Anecdotally, an acquaintance of mine has a secure "Job For Life" programming in Lisp. Nobody except the team can understand the code-base.क्या यह सच में उतना बुरा है? क्या उनके द्वारा जोड़े गए वैयक्तिकरण ने उन्हें अधिक उत्पादक बनाने में मदद नहीं की?
user6245072

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

क्या आप चल रहे लिस्प प्रोग्राम से यूनिट टेस्ट बनाने के लिए सिर्फ एक ट्रेसर का उपयोग नहीं कर सकते हैं? जैसे पायथन में आप एक डेकोरेटर (क्रिया विशेषण) बना सकते हैं जिसे print_args कहा जाता है जो एक फ़ंक्शन में लेता है और एक संशोधित फ़ंक्शन देता है जो इसके तर्क को प्रिंट करता है। फिर आप इसे sys.modules में पूरे प्रोग्राम पर लागू कर सकते हैं, हालांकि इसे करने का एक आसान तरीका sys.set_race का उपयोग करना है।
aoeu256

@ aoeu256 मैं लिस्प रनटाइम पर्यावरण क्षमताओं से परिचित नहीं हूं। लेकिन उन्होंने मैक्रोज़ का भारी उपयोग किया, इसलिए कोई भी सामान्य लिस्प प्रोग्रामर कोड नहीं पढ़ सकता था; यह संभावना है कि रनटाइम के लिए "सरल" चीजें करने की कोशिश मैक्रो के कारण लिस्प के बारे में सब कुछ बदलने के कारण काम नहीं कर सकती है।
टिम विस्क्रॉफ्ट ने

@TimWilliscroft आप तब तक प्रतीक्षा कर सकते हैं जब तक कि सभी मैक्रोज़ उस तरह के सामान को करने से पहले विस्तारित नहीं हो जाते। एमएसीएस में आपके पास मैक्रो (और इनलाइन फ़ंक्शन शायद) का विस्तार करने के लिए बहुत सी शॉर्टकट कुंजियाँ हैं।
aoeu256

4

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

यह आपके बारे में नहीं है कि आप रिटर्न प्रकार को भूल जाएं - यह हमेशा होने वाला है। यह उस टूल के बारे में है जो आपको यह बताने में सक्षम करता है कि आप रिटर्न प्रकार भूल गए हैं।

एक अतिरिक्त के रूप में, फ़ंक्शन प्रकार के साथ घोषित किए जाते हैं funcname()..., प्रकार जानने वाले व्हाइटआउट को आपको प्रत्येक पंक्ति पर खोज करना होगा जिसमें फ़ंक्शन कहा जाता है, क्योंकि आप केवल जानते हैं funcname, जबकि पायथन और इस तरह आप बस खोज कर सकते हैं def funcnameया function funcnameजो केवल एक बार होता है। घोषणा पर।

यह वाक्य रचना का विषय है, जो पूरी तरह से स्थैतिक टाइपिंग से असंबंधित है।

जब आप अपने निपटान में विशेष उपकरण के बिना एक घोषणा को देखना चाहते हैं तो सी परिवार वाक्यविन्यास वास्तव में अमित्र है। अन्य भाषाओं में यह समस्या नहीं है। देखें जंग की घोषणा सिंटैक्स:

fn funcname(a: i32) -> i32

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

किसी भी भाषा की व्याख्या की जा सकती है और किसी भी भाषा का REPL हो सकता है।


इसलिए, एक फ़ंक्शन के रिटर्न प्रकार को जानने के अलावा, जो स्पष्ट रूप से सांख्यिकीय रूप से टाइप की जाने वाली भाषाओं का एक मजबूत बिंदु नहीं है, स्थैतिक टाइपिंग वास्तव में बड़ी परियोजनाओं में कैसे सहायक है?

मैं एक अमूर्त तरीके से जवाब दूंगा।

एक प्रोग्राम में विभिन्न ऑपरेशन होते हैं और उन ऑपरेशनों को उस तरह से निर्धारित किया जाता है जैसे वे कुछ मान्यताओं के कारण होते हैं जो डेवलपर बनाता है।

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

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

मैं मान्यताओं को दो प्रकारों में वर्गीकृत करना चाहता हूं।

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

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

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

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

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

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


3

आपको पुरानी कहावत याद है "कचरा, कचरा बाहर", ठीक है, यह वही है जो स्थिर टाइपिंग को रोकने में मदद करता है। यह एक सार्वभौमिक रामबाण नहीं है लेकिन इस बात पर सख्ती है कि किस तरह का डेटा एक नियमित स्वीकार और रिटर्न का मतलब है कि आपके पास कुछ आश्वासन है कि आप इसके साथ सही तरीके से काम कर रहे हैं।

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

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


आपको स्टैटिक टाइप इनविज़न (पाइलिंट) करने की ज़रूरत नहीं है, आप डायनेमिक टाइप इनविज़न chrislaffra.blogspot.com/2016/12/… कर सकते हैं, जो PyPy के JIT कंपाइलर द्वारा भी किया जाता है। डायनामिक प्रकार के निष्कर्ष का एक और संस्करण भी है जहां एक कंप्यूटर बेतरतीब ढंग से वस्तुओं को तर्कों में रखता है और देखता है कि त्रुटि क्या होती है। रुकने की समस्या 99% मामलों के लिए मायने नहीं रखती है, यदि आप बहुत अधिक समय लेते हैं तो एल्गोरिथ्म को रोकें (यह है कि पायथन अनंत पुनरावृत्ति को कैसे संभालता है, इसकी एक पुनरावृत्ति सीमा है जिसे सेट किया जा सकता है)।
aoeu256
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.