अधिकांश "सुप्रसिद्ध" अनिवार्य / OO भाषाएँ उन प्रकारों की अनियंत्रित पहुँच की अनुमति देती हैं जो 'कुछ भी नहीं' का प्रतिनिधित्व कर सकते हैं?


29

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

एक उदाहरण के रूप में, निम्नलिखित C # कोड देखें:

void doSomething(string username)
{
    // Check that username is not null
    // Do something
}

यहाँ कुछ बदबू आ रही है ... अगर तर्क शून्य है तो हमें जाँच क्यों करनी चाहिए? क्या हमें यह नहीं मान लेना चाहिए कि हर चर में किसी वस्तु का संदर्भ होता है? जैसा कि आप देख सकते हैं, समस्या यह है कि परिभाषा के अनुसार लगभग सभी चर में एक शून्य संदर्भ हो सकता है। क्या होगा अगर हम तय कर सकते हैं कि कौन से चर "अशक्त" हैं और कौन से नहीं? यह डिबगिंग करते समय और "NullReferenceException" की तलाश में हमें बहुत सारे प्रयासों से बचाएगा। कल्पना करें कि, डिफ़ॉल्ट रूप से, किसी भी प्रकार में अशक्त संदर्भ नहीं हो सकता है । इसके बजाय, आप स्पष्ट रूप से बताएंगे कि एक चर में एक शून्य संदर्भ हो सकता है , केवल अगर आपको वास्तव में इसकी आवश्यकता है। शायद इसके पीछे का विचार है। यदि आपके पास एक फ़ंक्शन है जो कुछ मामलों में विफल रहता है (उदाहरण के लिए शून्य से विभाजन), तो आप वापस लौट सकते हैंMaybe<int>, स्पष्ट रूप से बताते हुए कि परिणाम एक int हो सकता है, लेकिन कुछ भी नहीं! यह अशक्त के बजाय शायद पसंद करने का एक कारण है । यदि आप अधिक उदाहरणों में रुचि रखते हैं, तो मैं इस लेख को पढ़ने का सुझाव देता हूं ।

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

  • किस तरह के तर्कों आप के लिए होता है को लागू करने nullके बजाय अपने प्रोग्रामिंग भाषा में Maybe? क्या सभी कारण हैं या यह सिर्फ "ऐतिहासिक सामान" है?

कृपया सुनिश्चित करें कि आप इस प्रश्न का उत्तर देने से पहले अशक्त और शायद अंतर के बीच अंतर को समझते हैं।


3
मेरा सुझाव है कि टोनी होरे के बारे में पढ़ना , विशेष रूप से उनकी अरब डॉलर की गलती।
Oded

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

9
ऐतिहासिक सामान को कम करके आंका नहीं है। और याद रखें कि ये OS जिस पर निर्मित होते हैं, उन भाषाओं में लिखे गए थे, जो nullलंबे समय से उनमें मौजूद थे। बस उसे गिराना आसान नहीं है।
Oded

3
मुझे लगता है कि आपको एक लिंक पोस्ट करने के बजाय हो सकता है कि अवधारणा पर कुछ प्रकाश डालना चाहिए।
जेएफओ

1
C # में GlenH7 स्ट्रिंग्स संदर्भ मूल्य हैं (वे शून्य हो सकते हैं)। मुझे पता है कि int एक आदिम मूल्य है, लेकिन यह शायद का उपयोग दिखाने के लिए उपयोगी था।
एनोचागविया

जवाबों:


15

मेरा मानना ​​है कि यह मुख्य रूप से ऐतिहासिक सामान है।

सबसे प्रमुख और सबसे पुरानी भाषा nullC और C ++ है। लेकिन यहाँ, nullसमझ में आता है। पॉइंटर्स अभी भी काफी संख्यात्मक और निम्न-स्तरीय अवधारणा हैं। और किसी और ने कैसे कहा, सी और सी ++ प्रोग्रामर की मानसिकता में, स्पष्ट रूप से यह बताने के लिए कि सूचक का nullकोई मतलब नहीं हो सकता है।

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

अन्य सभी भाषाएँ जावा जैसी ही हैं। वे आमतौर पर जिस तरह से सी ++ या जावा को कॉपी करते हैं, और यह देखते हुए कि nullसंदर्भ प्रकारों के निहितार्थ की मुख्य अवधारणा कैसे है, स्पष्ट रूप से उपयोग करने वाली भाषा को डिजाइन करना वास्तव में कठिन हो जाता है null


"वे शायद भाषा की ऐसी मूल अवधारणा के साथ खिलवाड़ नहीं करना चाहते थे" वे पहले से ही पूरी तरह से हटाए गए बिंदुओं को हटा रहे हैं, यह भी हटाने nullकि एक बड़ा बदलाव नहीं होगा, मुझे लगता है।
svick

2
@svick जावा के लिए, संदर्भ पॉइंटर्स के लिए प्रतिस्थापन हैं। और कई मामलों में, C ++ में पॉइंटर्स का उपयोग उसी तरह से किया गया था जैसा कि जावा संदर्भ करते हैं। कुछ लोग यह भी दावा करते हैं कि जावा में पॉइंटर्स ( प्रोग्रामर.स्टैकएक्सचेंज.
com

मैंने इसे सही उत्तर के रूप में चिह्नित किया है। मैं इसे उभारना चाहूंगा लेकिन मेरी पर्याप्त प्रतिष्ठा नहीं है।
एनोचागविया

1
इस बात से सहमत। ध्यान दें कि C ++ में (Java और C के विपरीत), शून्य-सक्षम होना अपवाद है। std::stringनहीं किया जा सकता nullint&नहीं किया जा सकता null। एक int*कर सकते हैं, और C ++ इसे दो कारणों से अनियंत्रित एक्सेस की अनुमति देता है: 1. क्योंकि C ने किया था और 2. क्योंकि आपको यह समझना चाहिए कि C ++ में कच्चे पॉइंटर्स का उपयोग करते समय आप क्या कर रहे हैं।
MSalters

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

15

वास्तव में, nullएक महान विचार है। एक पॉइंटर को देखते हुए, हम यह निर्दिष्ट करना चाहते हैं कि यह पॉइंटर वैध मान का संदर्भ नहीं देता है। इसलिए हम एक मेमोरी लोकेशन लेते हैं, इसे अमान्य घोषित करते हैं, और उस कन्वेंशन से चिपके रहते हैं (एक सम्मेलन कभी-कभी सेगफुल्स के साथ लागू किया जाता है)। अब जब भी मैं एक सूचक है मैं जाँच कर सकते हैं अगर यह होता है Nothing( ptr == null) या Some(value)( ptr != null, value = *ptr)। मैं चाहता हूं कि आप यह समझें कि यह एक Maybeप्रकार के बराबर है ।

इसके साथ समस्याएं हैं:

  1. कई भाषा में गैर-शून्य संदर्भ की गारंटी के लिए टाइप सिस्टम यहां सहायता नहीं करता है।

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

  2. API डिज़ाइनर nullविफलता पर लौट सकते हैं , लेकिन सफलता पर वास्तविक चीज़ का संदर्भ नहीं। अक्सर, बात (संदर्भ के बिना) सीधे लौटा दी जाती है। एक सूचक स्तर का यह समतल nullएक मूल्य के रूप में उपयोग करना असंभव बनाता है ।

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

  3. हास्केल Maybeमें एक साधु के रूप में साफ-सुथरा दृश्य होता है। इससे निहित मूल्य पर परिवर्तनों की रचना करना आसान हो जाता है।

    दूसरी ओर, निम्न-स्तरीय भाषाएं जैसे C, बमुश्किल सरणियों को एक अलग प्रकार के रूप में मानते हैं, इसलिए मुझे यकीन नहीं है कि हम क्या उम्मीद कर रहे हैं। पैरामीटरकृत बहुरूपता के साथ ओओपी भाषाओं में, एक रनटाइम-चेक Maybeप्रकार लागू करने के लिए तुच्छ है।


"C # अशक्त संदर्भों से कदम उठा रहा है।" वे कौन से चरण हैं? मैंने भाषा के परिवर्तनों में ऐसा कुछ नहीं देखा है। या क्या आपका मतलब सिर्फ इतना है कि आम पुस्तकालय nullअतीत की तुलना में कम उपयोग कर रहे हैं ?
svick

मेरे हिस्से पर @svick खराब वाक्यांश। " सी # एक मुख्य धारा भाषा है कि बेहतर संभाल करने के लिए भाषा के स्तर के उपकरण शुरू की है है nullरों " - मैं बात कर रहा हूँ Nullableप्रकार और ??डिफ़ॉल्ट ऑपरेटर। यह विरासत कोड की उपस्थिति में अभी समस्या का समाधान नहीं है, लेकिन यह है एक बेहतर भविष्य की ओर एक कदम है।
आमोन

मैं आपसे सहमत हूँ। मैं आपका जवाब दूंगा लेकिन मेरे पास पर्याप्त प्रतिष्ठा नहीं है :( हालांकि, अशक्त केवल आदिम प्रकारों के लिए काम करता है। इसलिए यह सिर्फ एक छोटा कदम है।
aochagavia

1
@svick Nullable का इससे कोई लेना-देना नहीं है। हम सभी संदर्भ प्रकारों के बारे में बात कर रहे हैं जो स्पष्ट रूप से शून्य मान की अनुमति देते हैं, इसके बजाय प्रोग्रामर इसे स्पष्ट रूप से परिभाषित करते हैं। और अशक्त केवल मूल्य प्रकारों पर उपयोग किया जा सकता है।
अशुभ

@ जोश से मुझे लगता है कि आपकी टिप्पणी एमन के जवाब के रूप में थी, मैंने उल्लेख नहीं किया Nullable
svick

9

मेरी समझ यह है कि nullविधानसभा से बाहर प्रोग्रामिंग भाषाओं को अमल में लाने के लिए एक आवश्यक निर्माण था। 1 प्रोग्रामर को यह इंगित करने की क्षमता की आवश्यकता थी कि एक सूचक या रजिस्टर मूल्य था not a valid valueऔर nullउस अर्थ के लिए सामान्य शब्द बन गया।

उस बिंदु को फिर nullसे लागू करना जो एक अवधारणा का प्रतिनिधित्व करने के लिए सिर्फ एक सम्मेलन है, nullप्रोग्रामिंग भाषा और मंच के आधार पर / के लिए उपयोग किए जाने वाले वास्तविक मूल्य में भिन्नता हो सकती है।

आप एक नई भाषा के डिजाइन और से बचना चाहता था रहे थे nullलेकिन का उपयोग maybeकरने के बजाय, तो मैं इस तरह के रूप में एक और वर्णनात्मक शब्द प्रोत्साहित करेगा not a valid valueया navvआशय का संकेत करने के। लेकिन नाम है कि गैर मूल्य की से है कि क्या आप चाहिए एक अलग अवधारणा है की अनुमति देने के लिए भी अपनी भाषा में मौजूद गैर मूल्यों।

इससे पहले कि आप उन दो बिंदुओं में से किसी एक पर निर्णय ले सकें, आपको यह परिभाषित करने की आवश्यकता है कि maybeआपके सिस्टम के लिए क्या अर्थ होगा। आप पा सकते हैं यह सिर्फ एक नाम का nullअर्थ है not a valid valueया आप पा सकते हैं यह आपकी भाषा के लिए एक अलग अर्थ है।

इसी तरह, nullउपयोग या संदर्भ के खिलाफ पहुंच की जांच करने का निर्णय आपकी भाषा का एक और डिजाइन निर्णय है।

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

मेरा मानना ​​है कि कुछ कंपाइलर या उनके अतिरिक्त टूलिंग अमान्य पॉइंटर एक्सेस के खिलाफ जांच का एक उपाय प्रदान कर सकते हैं। इसलिए अन्य लोगों ने इस संभावित मुद्दे पर ध्यान दिया और इससे बचाव के उपाय किए।

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

तो आपके सवालों का जवाब देने के लिए:

  1. "किस तरह के तर्क ..." - यह इस बात पर निर्भर करता है कि आप क्या करना चाहते हैं। यदि आप नंगे-धातु पहुंच का अनुकरण करना चाहते हैं तो आप इसे अनुमति देना चाह सकते हैं।

  2. "क्या यह सिर्फ ऐतिहासिक सामान है?" शायद, शायद नहीं। nullनिश्चित रूप से कई भाषाओं के लिए अर्थ है / और उन भाषाओं की अभिव्यक्ति को चलाने में मदद करता है। ऐतिहासिक मिसाल ने हाल की भाषाओं और उनकी अनुमति को प्रभावित किया हो सकता है nullलेकिन यह आपके हाथों को लहराने और अवधारणा को बेकार ऐतिहासिक सामान घोषित करने के लिए थोड़ा बहुत है।


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


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

2
"नल सूचक संदर्भ संकलन के दौरान त्रुटियों के रूप में दिखाई दे सकते हैं" कौन से संकलक ऐसा कर सकते हैं?
svick

पूरी तरह से निष्पक्ष होने के लिए, आप कभी भी किसी ऑब्जेक्ट के लिए एक अशक्त संदर्भ नहीं देते हैं ... ऑब्जेक्ट का संदर्भ बस मौजूद नहीं है (संदर्भ कुछ भी नहीं (0x000000000), जो परिभाषा के अनुसार है null)।
mgw854

C99 युक्ति की बोली अशक्त चरित्र के बारे में बात करती है , न कि शून्य सूचक के बारे में , वे दो बहुत भिन्न अवधारणाएँ हैं।
svick

2
@ GlenH7 यह मेरे लिए नहीं है। object o = null; o.ToString();VS2012 में त्रुटियों या चेतावनियों के बिना, कोड मेरे लिए ठीक है। ReSharper उस के बारे में शिकायत करता है, लेकिन वह संकलक नहीं है।
svick

7

यदि आप लेख में दिए गए उदाहरणों को देखते हैं, तो अधिकांश समय का उपयोग Maybeकोड को छोटा नहीं करता है। यह जाँच करने की आवश्यकता को कम नहीं करता है Nothing। एकमात्र अंतर यह है कि यह आपको टाइप सिस्टम के माध्यम से ऐसा करने की याद दिलाता है।

ध्यान दें, मैं कहता हूं "याद दिलाना", बलपूर्वक नहीं। प्रोग्रामर आलसी होते हैं। यदि एक प्रोग्रामर आश्वस्त है कि एक मूल्य संभवतः नहीं हो सकता है Nothing, तो वे Maybeइसे जाँच के बिना बिना किसी शर्त के जा रहे हैं , जैसे वे अब एक अशक्त सूचक को रोकते हैं। अंतिम परिणाम यह है कि आप एक अशक्त पॉइंटर अपवाद को "डीएफ़रफ़ाइन्ड खाली शायद" अपवाद में बदल सकते हैं।

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

क्या Maybeअच्छा है जब बहुत सारे निर्णय स्पष्ट जांच के बजाय पैटर्न मिलान और बहुरूपता के माध्यम से किए जाते हैं। उदाहरण के लिए, आप अलग-अलग कार्य कर सकते हैं processData(Some<T>)और processData(Nothing<T>), जो आप नहीं कर सकते null। आप स्वचालित रूप से अपनी त्रुटि को एक अलग फ़ंक्शन में ले जाते हैं, जो कार्यात्मक प्रोग्रामिंग में बहुत ही वांछनीय है, जहां फ़ंक्शन को पास किया जाता है और हमेशा टॉप-डाउन तरीके से कॉल करने के बजाय आलसी का मूल्यांकन किया जाता है। OOP में, आपकी त्रुटि हैंडलिंग कोड को डिकॉप करने का पसंदीदा तरीका अपवादों के साथ है।


क्या आपको लगता है कि यह एक नई OO भाषा में एक वांछित विशेषता होगी?
एनोचागविया

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

2
हालांकि आपको शायद प्रकार के साथ जांच नहीं करनी है। हो सकता है कि प्रकार एक सन्यासी है, इसलिए इसमें फ़ंक्शन होने चाहिए map :: Maybe a -> (a -> b) और bind :: Maybe a -> (a -> Maybe b)इसे परिभाषित किया जाना चाहिए , इसलिए आप जारी रख सकते हैं और यदि किसी अन्य कथन का उपयोग करते हुए सबसे अधिक भाग के लिए गणना कर सकते हैं। और getValueOrDefault :: Maybe a -> (() -> a) -> aआपको अशक्त मामले को संभालने की अनुमति देता है। यह Maybe aस्पष्ट रूप से पैटर्न से अधिक सुरुचिपूर्ण है ।
डेट्रिएक्सएक्सआई

1

Maybeकिसी समस्या के बारे में सोचने का एक बहुत ही कार्यात्मक तरीका है - एक चीज है, और यह एक मान हो सकता है या नहीं हो सकता है। वस्तु-उन्मुख अर्थ में, हालांकि, हम किसी वस्तु के उस विचार को प्रतिस्थापित करते हैं (भले ही उसका कोई मूल्य हो या नहीं)। स्पष्ट रूप से, किसी वस्तु का एक मूल्य होता है। यदि ऐसा नहीं है, तो हम कहते हैं कि वस्तु है null, लेकिन हमारा वास्तव में मतलब यह है कि कोई वस्तु नहीं है। वस्तु के संदर्भ में हमें कुछ नहीं करना है। Maybeएक OO अवधारणा में अनुवाद करने से उपन्यास कुछ भी नहीं होता है - वास्तव में, यह सिर्फ बहुत अधिक अव्यवस्थित कोड के लिए बनाता है। आपके पास अभी भी मान के लिए एक अशक्त संदर्भ होना चाहिएMaybe<T>। आपको अभी भी अशक्त चेक करना है (वास्तव में, आपको बहुत अधिक शून्य चेक करना होगा, अपने कोड को अव्यवस्थित करना होगा), भले ही उन्हें अब "शायद चेक" कहा जाता है। निश्चित रूप से, आप लेखक के दावों के अनुसार अधिक मजबूत कोड लिखेंगे, लेकिन मैं तर्क दूंगा कि यह केवल मामला है क्योंकि आपने भाषा को अधिक सारगर्भित और अप्रिय बना दिया है, ऐसे कार्य की आवश्यकता होती है जो अधिकांश मामलों में अनावश्यक हो। मैं स्वेच्छा से एक बार एक NullReferenceException ले जाऊँगा, जबकि स्पेगेटी कोड के साथ सौदा करने की तुलना में एक बार शायद मैं हर बार एक नए चर का उपयोग कर सकता हूं।


2
मुझे लगता है कि यह कम अशक्त जांच को जन्म देगा, क्योंकि आपको केवल यह जांचना है कि क्या आप शायद एक <टी> देखते हैं और बाकी प्रकारों के बारे में चिंता करने की ज़रूरत नहीं है।
एनोचागविया

1
@svick Maybe<T>को nullमान के रूप में अनुमति देना है , क्योंकि मान मौजूद नहीं हो सकता है। यदि मेरे पास है Maybe<MyClass>, और इसका कोई मूल्य नहीं है, तो मान फ़ील्ड में एक शून्य संदर्भ होना चाहिए। इसके लिए और कुछ भी नहीं है जो वास्तव में सुरक्षित हो।
mgw854

1
@ mgw854 ज़रूर है। OO भाषा में, Maybeएक अमूर्त वर्ग हो सकता है, जिसमें दो वर्ग हैं जो इसे प्राप्त करते हैं: Some(जिसमें मान के लिए एक फ़ील्ड है) और None(जिसके पास वह फ़ील्ड नहीं है)। इस तरह, मूल्य कभी नहीं होता है null
svick

6
डिफ़ॉल्ट रूप से "नहीं-अशक्तता" के साथ, और शायद <टी> आप निश्चित हो सकते हैं कि कुछ चर में हमेशा ऑब्जेक्ट होते हैं। अर्थात्, सभी चर जो शायद नहीं हैं <T>
एनोचागाविया

3
@ mgw854 इस परिवर्तन के विकासकर्ता के लिए अभिव्यंजक शक्ति में वृद्धि होगी। अभी, डेवलपर को हमेशा यह मानना ​​पड़ता है कि संदर्भ या सूचक शून्य हो सकता है और यह सुनिश्चित करने के लिए जांच करने की आवश्यकता है कि उपयोग करने योग्य मूल्य है। इस परिवर्तन को लागू करके, आप डेवलपर को यह कहने की शक्ति देते हैं कि उसे वास्तव में एक वैध मूल्य की आवश्यकता है और मान्य मान पारित करने के लिए संकलक की जांच होनी चाहिए। लेकिन अभी भी डेवलपर विकल्प दे रहा है, ऑप्ट-इन करने के लिए और मूल्य-पास नहीं है।
व्यंग्य

1

nullआसानी से C की अवधारणा का पता लगाया जा सकता है, लेकिन यह वह जगह नहीं है जहाँ समस्या निहित है।

मेरी पसंद की रोजमर्रा की भाषा C # है और मैं nullएक अंतर के साथ रखूंगा। C # के दो प्रकार हैं, मान और संदर्भ । मान कभी नहीं हो सकते null, लेकिन कई बार मैं यह व्यक्त करना चाहूंगा कि कोई भी मूल्य पूरी तरह से ठीक नहीं है। ऐसा करने के लिए C # Nullableप्रकारों का उपयोग करता है इसलिए intमूल्य और int?अशक्त मूल्य होगा। मुझे लगता है कि संदर्भ प्रकारों को भी काम करना चाहिए।

यह भी देखें: अशक्त संदर्भ गलती नहीं हो सकती है :

अशक्त संदर्भ सहायक होते हैं और कभी-कभी अपरिहार्य होते हैं (विचार करें कि यदि आप C ++ में स्ट्रिंग नहीं लौटा सकते हैं या नहीं तो कितनी परेशानी होगी)। गलती वास्तव में अशक्त बिंदुओं के अस्तित्व में नहीं है, लेकिन प्रकार प्रणाली उन्हें कैसे संभालती है। दुर्भाग्य से अधिकांश भाषाएँ (C ++, Java, C #) उन्हें सही ढंग से नहीं संभालती हैं।


0

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

प्रोग्रामिंग भाषाओं के आधुनिक संस्करण जो मुझे लगता है कि आप (C ++, C #, Java) के बारे में बात कर रहे हैं, वे सभी ऐसी भाषाओं पर आधारित हैं जिनमें सामान्य प्रोग्रामिंग (C, C # 1.0, Java 1) का कोई रूप नहीं था। इसके बिना, आप अभी भी भाषा में अशक्त और गैर-अशक्त वस्तुओं के बीच कुछ प्रकार के अंतर को सेंक सकते हैं (जैसे सी ++ संदर्भ, जो nullसीमित नहीं हो सकते हैं), लेकिन यह बहुत कम प्राकृतिक है।


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

0

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

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


यह पोस्ट पढ़ना मुश्किल है (पाठ की दीवार)। आप आपत्ति तो नहीं है संपादित एक बेहतर आकार में यह ing?
गिन्नत २।

1
@gnat: क्या यह बेहतर है?
सुपरकैट

0

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

आप शायद एक ऐसी भाषा के साथ कार्यान्वयन कर सकते हैं जिसमें आसानी से नल हो। C ++ में एक के रूप में है boost::optional<T>। शायद के साथ अशक्त के बराबर बनाना बहुत मुश्किल है। विशेष रूप से, अगर मेरे पास एक है, तो मैं Maybe<Just<T>>इसे अशक्त करने के लिए निर्दिष्ट नहीं कर सकता (क्योंकि ऐसी अवधारणा मौजूद नहीं है), जबकि T**अशक्त भाषा में अशक्त को सौंपना बहुत आसान है। यह एक का उपयोग करने के लिए मजबूर करता है Maybe<Maybe<T>>, जो पूरी तरह से वैध है, लेकिन आपको उस वस्तु का उपयोग करने के लिए कई और जांच करने के लिए मजबूर करेगा।

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

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