कार्यात्मक प्रोग्रामिंग में साइड-इफेक्ट्स को बुराई क्यों माना जाता है?


69

मुझे लगता है कि साइड इफेक्ट एक प्राकृतिक घटना है। लेकिन यह कार्यात्मक भाषाओं में वर्जित की तरह है। कारण क्या हैं?

मेरा प्रश्न कार्यात्मक प्रोग्रामिंग शैली के लिए विशिष्ट है। सभी प्रोग्रामिंग भाषा / प्रतिमान नहीं।


6
साइड इफेक्ट्स के बिना एक कार्यक्रम बेकार है, इसलिए साइड इफेक्ट्स न तो बुराई हैं और न ही वर्जित हैं। लेकिन एफपी साइड इफेक्ट्स के साथ कोड को डिलिमिट करने को प्रेरित करता है, इसलिए कोड का एक बड़ा हिस्सा साइड-इफेक्ट फ्री फ़ंक्शंस हैं। इसे प्रोत्साहित किया जाता है क्योंकि साइड-इफेक्ट फ्री फ़ंक्शंस और सबसिस्टम को समझना आसान है, विश्लेषण करना आसान है, परीक्षण करना आसान है और अनुकूलन करना आसान है।
जैक्सबी

@JacquesB यह समझाने के लिए एक अच्छा उत्तर देगा कि उन्हें समझना आसान क्यों है, विश्लेषण करना आसान है, परीक्षण करना आसान है और अनुकूलन करना आसान है।
16-16 को छत

जवाबों:


72

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

नए कार्यों को बनाने के लिए उन कार्यों की रचना करना भी आसान बनाता है।

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

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

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


4
हो सकता है कि अपने उत्तर में संगामिति के बारे में कुछ जोड़ने पर विचार करें?
बेंजोल

5
साइड-इफ़ेक्ट फ्री फ़ंक्शंस का परीक्षण करना और पुन: उपयोग करना आसान है।
लेनिप्रोग्रामर्स

@ Lenny222: पुन: उपयोग मैं क्या समारोह संरचना के बारे में बात करके इशारा कर रहा था।
फ्रैंक शीयर

@ चरण: आह, ठीक है, बहुत उथले ब्राउज़िंग। :)
लेनिप्रोग्रामर्स

@ Lenny222: यह ठीक है; इसे बाहर निकालना शायद अच्छी बात है।
फ्रैंक शियरर

23

कार्यात्मक प्रोग्रामिंग के बारे में एक लेख से :

व्यवहार में, अनुप्रयोगों को कुछ दुष्प्रभाव होने चाहिए। साइमन पेयटन-जोन्स, कार्यात्मक प्रोग्रामिंग भाषा हास्केल के लिए एक प्रमुख योगदानकर्ता ने निम्नलिखित कहा: "अंत में, किसी भी कार्यक्रम को राज्य में हेरफेर करना होगा। एक प्रोग्राम जिसमें कोई साइड इफेक्ट नहीं है जो एक तरह का ब्लैक बॉक्स है। आप सभी को बता सकते हैं। वह बॉक्स गर्म हो जाता है। " ( http://oscon.blip.tv/file/324976 ) कुंजी साइड इफेक्ट्स को सीमित करने के लिए है, स्पष्ट रूप से उन्हें पहचानें, और कोड में उन्हें बिखेरने से बचें।


2
oscon.blip.tv/file/324976 को youtube.com/watch?v=iSmkqocn0oQ&t=3m20s से बदल दिया गया है ।
गौरव

23

आपको यह गलत है, कार्यात्मक प्रोग्रामिंग कार्यक्रमों को समझने और अनुकूलित करने के लिए आसान बनाने के लिए साइड इफेक्ट्स को सीमित करता है। यहां तक ​​कि हास्केल आपको फ़ाइलों को लिखने की अनुमति देता है।

अनिवार्य रूप से मैं यह कह रहा हूं कि कार्यात्मक प्रोग्रामर नहीं सोचते कि साइड इफेक्ट्स बुरे हैं, वे बस सोचते हैं कि साइड इफेक्ट्स का उपयोग सीमित है या नहीं। मुझे पता है कि यह एक साधारण अंतर की तरह लग सकता है लेकिन इससे सभी फर्क पड़ता है।


यही कारण है कि वे "वर्जित जैसा कुछ" हैं - एफपीएल आपको दुष्प्रभावों को सीमित करने के लिए प्रोत्साहित करते हैं।
फ्रैंक शियरार

दृष्टिकोण के लिए +1। दुष्प्रभाव अभी भी मौजूद हैं। वास्तव में, वे सीमित हैं
बेलुन

स्पष्टीकरण के लिए, मैंने यह नहीं कहा है कि 'कार्यात्मक प्रोग्रामिंग में साइड इफेक्ट की अनुमति नहीं है' या 'साइड इफेक्ट की आवश्यकता क्यों नहीं है'। मुझे पता है कि कार्यात्मक भाषाओं में इसकी अनुमति है और कभी-कभी यह आवश्यक है। लेकिन यह कार्यात्मक प्रोग्रामिंग में बहुत हतोत्साहित है। क्यों? यह मेरा सवाल था।
गुलशन

@ गुलशन - क्योंकि साइड इफेक्ट्स प्रोग्राम को समझने और ऑप्टिमाइज़ करने में कठिन बनाते हैं।
ChaosPandion

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

13

कुछ नोट:

  • साइड इफेक्ट के बिना कार्यों को समानांतर में निष्पादित किया जा सकता है, जबकि साइड इफेक्ट वाले कार्यों को आमतौर पर किसी प्रकार के सिंक्रनाइज़ेशन की आवश्यकता होती है।

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


बहुत दिलचस्प बिंदु: यह भी कोई फर्क नहीं पड़ता कि फ़ंक्शन वास्तव में निष्पादित किया गया था या नहीं । यह एक संकलक के साथ समाप्त होने के लिए दिलचस्प होगा जो बाद के कॉल से छुटकारा पा सकता है साइड इफेक्ट फ्री कार्यों के बराबर पैरामीटर दिए गए हैं।
नोएल विडमर

1
@NoelWidmer कुछ ऐसा है जो पहले से मौजूद है। ओरेकल के पीएल / एसक्यूएल deterministicसाइड इफेक्ट्स के बिना फ़ंक्शन के लिए एक खंड प्रदान करता है , इसलिए वे आवश्यक से अधिक बार निष्पादित नहीं होते हैं।
user281377

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

deterministicखंड सिर्फ एक कीवर्ड कि संकलक यह एक नियतात्मक समारोह, करने के लिए कैसे तुलनीय है कि बताता है finalजावा में कीवर्ड संकलक कि चर को बदल नहीं सकते बताता है।
user281377

11

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

इस सरल उदाहरण पर विचार करें:

val foo = 42
// Several lines of code you don't really care about, but that contain a
// lot of function calls that use foo and may or may not change its value
// by side effect.

// Code you are troubleshooting
// What's the expected value of foo here?

एक कार्यात्मक भाषा में, मुझे पता है कि fooअभी भी 42 है। मुझे बीच में कोड को देखने की ज़रूरत नहीं है, यह बहुत कम समझ में आता है, या इसके द्वारा किए जाने वाले फ़ंक्शन के कार्यान्वयन को देखें।

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


6

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

साइड-इफेक्ट्स को बुराई क्यों माना जाता है?

क्योंकि वे वास्तव में एक कार्यक्रम में क्या करते हैं, और यह साबित करने के लिए यह अधिक कठिन बना देता है कि यह वही करता है जो आप इसे करने की अपेक्षा करते हैं।

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

लाभ

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

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

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


1
Ada से साइड-इफ़ेक्ट पैदा करना बहुत मुश्किल हो जाता है। हालांकि यह असंभव नहीं है, लेकिन आप स्पष्ट रूप से जानते हैं कि आप तब क्या करते हैं।
मौविसील

@ माउवीसील: मुझे लगता है कि कम से कम कुछ उपयोगी भाषाएं हैं जो साइड-इफेक्ट्स को बहुत मुश्किल बनाती हैं, और उन्हें मोनाड्स को फिर से लागू करने की कोशिश करते हैं।
मेरलिन मॉर्गन-ग्राहम

4

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

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

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


+1 - "या कुछ अनसुने सहकर्मी"
मेरलिन मॉर्गन-ग्राहम

1
-1 साइड इफेक्ट्स के लिए "लीक जिन्हें संभालने की जरूरत है।" "साइड इफेक्ट्स" (गैर-शुद्ध-कार्यात्मक कोड) बनाना किसी भी गैर-तुच्छ कंप्यूटर प्रोग्राम को लिखने का संपूर्ण उद्देश्य है।
मेसन व्हीलर

यह टिप्पणी छह साल बाद आती है, लेकिन इसके साइड इफेक्ट्स हैं और फिर साइड इफेक्ट्स हैं। वांछित प्रकार के दुष्प्रभाव, I / O और इसी तरह करना, वास्तव में किसी भी कार्यक्रम के लिए आवश्यक हैं, क्योंकि आपको उपयोगकर्ता को किसी भी तरह अपने परिणाम देने की आवश्यकता है - लेकिन दूसरी तरह के दुष्प्रभाव, जहां आपका कोड एक अच्छा बिना राज्य बदलता है I / O करने जैसे कारण, वास्तव में एक "लीक" है जिसे बाद में संभालने की आवश्यकता होगी। मूल विचार कमांड-क्वेरी अलगाव है : एक फ़ंक्शन जो मान लौटाता है उसका साइड इफेक्ट नहीं होना चाहिए।
r

4

खैर, IMHO, यह काफी पाखंडी है। किसी को भी साइड इफेक्ट्स पसंद नहीं हैं, लेकिन हर किसी को उनकी जरूरत होती है।

साइड इफेक्ट्स के बारे में इतना खतरनाक है कि यदि आप किसी फ़ंक्शन को कॉल करते हैं, तो संभवतः इसका प्रभाव न केवल उस तरह से होता है, जब फ़ंक्शन अगली बार कॉल किया जाता है, बल्कि संभवतः अन्य कार्यों पर भी इसका प्रभाव पड़ता है। इस प्रकार साइड इफेक्ट अप्रत्याशित व्यवहार और nontrivial निर्भरता का परिचय देते हैं।

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

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

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


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

@ इलन: यह कुछ कार्यात्मक भाषाओं के लिए भी सही है और इसे अपनाना आसान है।
बैकऑडोस

"कार्यात्मक प्रोग्रामिंग कहीं अधिक कट्टरपंथी दृष्टिकोण लेता है, जहां एप्लिकेशन राज्य प्रोग्रामर के दृष्टिकोण से बस अपरिवर्तनीय है। यह एक अच्छा विचार है, लेकिन अपने दम पर भाषा को बेकार कर देता है। क्यों? क्योंकि किसी भी I / O- ऑपरेशन की ओर है। प्रभाव ": एफपी साइड-इफेक्ट्स को मना नहीं करता है, यह आवश्यक नहीं होने पर उन्हें प्रतिबंधित करता है। जैसे (1) I / O -> दुष्प्रभाव आवश्यक हैं; (2) मूल्यों के अनुक्रम से एक समग्र कार्य की गणना करना -> साइड इफेक्ट (जैसे संचायक चर के साथ लूप के लिए) आवश्यक नहीं है।
जियोर्जियो

2

कोई भी साइड-इफेक्ट अतिरिक्त इनपुट / आउटपुट पैरामीटर का परिचय देता है जिसे परीक्षण करते समय ध्यान में रखा जाना चाहिए।

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

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


1

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में मेरे अनुभव के अच्छे डिज़ाइन में साइड इफेक्ट्स वाले कार्यों का उपयोग अनिवार्य है।

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

इन ढेर-संशोधन और स्क्रीन-संशोधित साइड इफेक्ट्स की सही व्यवस्था की बुराई से दूर OO डिजाइन के मूल में हैं (इस मामले में MVC पैटर्न)।

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


1
पर्यवेक्षकों (UI सहित) को उन संदेशों / घटनाओं की सदस्यता के माध्यम से संशोधनों के बारे में पता लगाना चाहिए जिन्हें आपकी वस्तु बाहर भेजती है। यह एक पक्ष प्रभाव नहीं है जब तक कि वस्तु सीधे पर्यवेक्षक को संशोधित नहीं करती है - जो खराब डिजाइन होगा।
ChrisF

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

0

बुराई थोड़ा ऊपर है .. यह सब भाषा के उपयोग के संदर्भ पर निर्भर करता है।

पहले से ही उल्लेखित लोगों के लिए एक और विचार यह है कि यह प्रोग्राम के सही होने के प्रमाण को सरल बनाता है यदि कोई कार्यात्मक दुष्प्रभाव नहीं हैं।


0

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

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

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

0

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

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

लेकिन मैं एक व्यावहारिक प्रकार हूं, मुझे लगता है, या कम से कम होने की कोशिश करो, और मुझे नहीं लगता कि हमारे पास हमारे कोड की शुद्धता के बारे में तर्क करने के लिए न्यूनतम न्यूनतम करने के लिए सभी साइड इफेक्ट्स पर मुहर लगाना जरूरी है (बहुत कम से कम मुझे C) जैसी भाषाओं में ऐसा करना बहुत मुश्किल होगा। जहां मुझे शुद्धता के बारे में तर्क करना बहुत मुश्किल लगता है, जब हमारे पास जटिल नियंत्रण प्रवाह और दुष्प्रभावों का संयोजन होता है।

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

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

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

for each pixel in an image:
    make it red

इस तरह के कोड की शुद्धता के बारे में तर्क करना बहुत आसान है, लेकिन मुख्य रूप से क्योंकि दुष्प्रभाव इतने समान हैं और नियंत्रण प्रवाह इतना आसान है। लेकिन मान लें कि हमारे पास इस तरह का कोड था:

for each vertex to remove in a mesh:
     start removing vertex from connected edges():
         start removing connected edges from connected faces():
             rebuild connected faces excluding edges to remove():
                  if face has less than 3 edges:
                       remove face
             remove edge
         remove vertex

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

for each vertex to remove:
     mark connected edges
for each marked edge:
     mark connected faces
for each marked face:
     remove marked edges from face
     if num_edges < 3:
          remove face

for each marked edge:
     remove edge
for each vertex to remove:
     remove vertex

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

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


-1

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


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