2012-05-22 10 views
27

side effect के लिए विकिपीडिया प्रविष्टि के अनुसार, अपवाद को बढ़ाने से दुष्प्रभाव का गठन होता है। इस सरल अजगर समारोह पर विचार करें:एक अपवाद को साइड इफेक्ट क्यों बढ़ा रहा है?

def foo(arg): 
    if not arg: 
     raise ValueError('arg cannot be None') 
    else: 
     return 10 

foo(None) के साथ लागू हमेशा एक अपवाद के साथ मुलाकात की जाएगी। वही इनपुट, एक ही आउटपुट। यह संदर्भित पारदर्शी है। यह एक शुद्ध कार्य क्यों नहीं है?

+0

अपवाद केवल वापसी मूल्य के रूप में वापस नहीं किया जाता है। – Sjoerd

+4

इसे फिर से खोलने के लिए आगे बढ़ना एक प्रश्न है, जबकि प्रकृति में अधिक सैद्धांतिक अभी भी इस वेबसाइट के लिए मान्य है। – Woot4Moo

+0

इसे [programmers.se] – Daenyth

उत्तर

10

पहली पंक्ति से:

"कंप्यूटर विज्ञान में, एक समारोह या अभिव्यक्ति है, एक मूल्य के लौटने के अलावा, यह भी कुछ राज्य को संशोधित करता है या एक है एक पक्ष प्रभाव कहा जाता है कि कार्य या बाहर की दुनिया "

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

+0

समाप्ति एक प्रभाव नहीं है। यह राज्य नहीं है जिसे साझा किया जा सकता है। कई शुद्ध, आंशिक कार्य समाप्त नहीं होते हैं, या केवल आंशिक रूप से परिभाषित किए जाते हैं। वे अभी भी शुद्ध हैं। शून्य से विभाजन एक शुद्ध कार्य है, उदाहरण के लिए, जो विफल रहता है। –

+5

डॉन: असल में, गैर-समाप्ति (उर्फ पक्षपात) अक्सर * प्रभाव * माना जाता है, विशेष रूप से जहां लोग करी/हॉवर्ड आइसोमोर्फिज्म की कटाई में रुचि रखते हैं और प्रस्तावों के रूप में प्रकारों का उपयोग करते हैं। –

+0

ठीक है। अगर हम कुल और आंशिक कार्यों को अलग कर रहे हैं तो मैं इसे खरीदूंगा। –

4

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

+1

ठीक है, अगर कोई अपवाद नहीं है तो यह सच हो सकता है। लेकिन अगर वहां हैं, तो आप फ़ंक्शन निष्पादित करने के बजाय केवल अपवाद फेंक सकते हैं (फ़ंक्शन निष्पादित करने के बजाए मान को वापस करने के लिए एनालॉग)। – valenterry

24

शुद्धता केवल तभी उल्लंघन की जाती है जब आप अपवाद का पालन करते हैं, और उस पर आधारित निर्णय लेते हैं जो नियंत्रण प्रवाह को बदलता है। असल में एक अपवाद मूल्य फेंकने referentially पारदर्शी है - यह अर्थ की दृष्टि से गैर समाप्ति या अन्य के बराबर है तथाकथित bottom values.

एक (शुद्ध) समारोह total नहीं है, तो यह एक नीचे मूल्य के लिए मूल्यांकन करता है। आप नीचे मान को एन्कोड कैसे करते हैं कार्यान्वयन तक है - यह एक अपवाद हो सकता है; या गैर-समाप्ति, या शून्य से विभाजित, या कुछ अन्य विफलता।

f :: Int -> Int 
f 0 = 1 
f 1 = 2 

यह सभी इनपुट के लिए परिभाषित नहीं है:

शुद्ध कार्य पर विचार करें। कुछ के लिए यह नीचे मूल्यांकन करता है। कार्यान्वयन एक अपवाद फेंक कर इसे एन्कोड करता है। यह Maybe या Option प्रकार का उपयोग करने के लिए अर्थात् समकक्ष होना चाहिए।

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

तो यह सच नहीं है कि अपवाद उठाना इस तरह का दुष्प्रभाव है। यह एक असाधारण मूल्य के आधार पर शुद्ध कार्य के व्यवहार को संशोधित कर सकता है या नहीं - इस प्रकार संदर्भित पारदर्शिता तोड़ना - यह मुद्दा है।

+2

दिलचस्प, मैंने हमेशा सोचा था कि आरटी की परिभाषा यह थी कि यदि आप अभिव्यक्ति को इसके मूल्य के साथ बदल सकते हैं, और आपके पास "अपवाद ए फेंकता" का कोई मूल्य नहीं हो सकता है। –

+0

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

4

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

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

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

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

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

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

संबंधित मुद्दे