कार्यात्मक प्रोग्रामिंग के संदर्भ में क्या गलत हो सकता है अगर मेरी वस्तु पारस्परिक है?


9

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

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

मैं वास्तविक ठोस उदाहरण की तलाश कर रहा हूं जहां यह बहुत स्पष्ट है कि फ़ंक्शन प्रोग्रामिंग में उत्परिवर्तनीय वस्तु का उपयोग करके क्या गलत हो सकता है। मूल रूप से अगर यह खराब है, तो यह ओओ या कार्यात्मक प्रोग्रामिंग प्रतिमान के बावजूद बुरा है, है ना?

मेरा मानना ​​है कि मेरे स्वयं के कथन के नीचे स्वयं इस प्रश्न का उत्तर है। लेकिन फिर भी मुझे कुछ उदाहरण की आवश्यकता है ताकि मैं इसे स्वाभाविक रूप से महसूस कर सकूं।

OO निर्भरता को प्रबंधित करने और इनकैप्सुलेशन, बहुरूपता आदि जैसे उपकरणों की सहायता से आसान और बनाए रखने योग्य कार्यक्रम लिखने में मदद करता है।

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


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

1
मुझे लगता है कि आप अपने पहले पैराग्राफ में मिश्रित अपरिवर्तनीय और परिवर्तनशील हो सकते हैं?
जे.के.

1
@jk।, वह निश्चित रूप से किया था। सही करने के लिए संपादित किया गया।
डेविड अरनो

6
@ रूबेन फंक्शनल प्रोग्रामिंग एक प्रतिमान है। जैसे कि यह एक कार्यात्मक प्रोग्रामिंग भाषा की आवश्यकता नहीं है। और कुछ fp भाषाओं जैसे F # में यह सुविधा है
क्रिस्टोफ़

1
@Ruben कोई विशेष रूप से मैं हास्केल में Mvars की सोच रहा था hackage.haskell.org/package/base-4.9.1.0/docs/... विभिन्न भाषाओं की है निश्चित रूप से अलग अलग समाधान या IORefs hackage.haskell.org/package/base-4.11.1.0 /docs/Data-IORef.html हालाँकि आप दोनों का उपयोग भिक्षुओं
jk के

जवाबों:


7

मुझे लगता है कि OO दृष्टिकोण की तुलना करके महत्व को सबसे अच्छा प्रदर्शित किया जाता है

उदाहरण के लिए, मान लें कि हमारे पास एक वस्तु है

Order
{
    string Status {get;set;}
    Purchase()
    {
        this.Status = "Purchased";
    }
}

OO प्रतिमान में विधि डेटा से जुड़ी होती है, और यह उस डेटा को विधि द्वारा उत्परिवर्तित करने के लिए समझ में आता है।

var order = new Order();
order.Purchase();
Console.WriteLine(order.Status); // "Purchased"

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

var order = new Order(); //this is a 'new order'
var purchasedOrder = purchase(order); // this is a 'purchased order'
Console.WriteLine(order.Status); // "New" order is still a 'new order'

क्या आप ऑर्डर की उम्मीद करेंगे। सत्तुस == "खरीदे गए"?

इसका तात्पर्य यह भी है कि हमारे कार्य निष्प्राण हैं। अर्थात। उन्हें दो बार चलाने से हर बार एक ही परिणाम प्राप्त होना चाहिए।

var order = new Order(); //new order
var purchasedOrder = purchase(order); //purchased order
var purchasedOrder2 = purchase(order); //another purchased order
var purchasedOrder = purchase(purchasedOrder); //error! cant purchase an order twice

यदि ऑर्डर को खरीद फ़ंक्शन द्वारा बदल दिया गया, तो buyOrder2 विफल हो जाएगा।

कार्यों के परिणामों के रूप में चीजों को परिभाषित करने से यह हमें उन परिणामों का उपयोग करने की अनुमति देता है जो वास्तव में उनकी गणना किए बिना। प्रोग्रामिंग की शर्तों में निष्पादन को स्थगित कर दिया गया है।

यह स्वयं के लिए आसान हो सकता है, लेकिन एक बार जब हम इस बारे में अनिश्चित होते हैं कि कोई फ़ंक्शन वास्तव में होगा और हम इसके बारे में ठीक हैं, तो हम एक OO प्रतिमान में जितना हो सके समानांतर प्रसंस्करण का लाभ उठा सकते हैं।

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

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


धन्यवाद !! बहुत मददगार। इसलिए खरीद का नया कार्यान्वयन ऐसा लगेगा Order Purchase() { return new Order(Status = "Purchased") } कि स्थिति केवल फ़ील्ड पढ़ी जाती है। ? फ़ंक्शन प्रोग्रामिंग प्रतिमान के संदर्भ में यह अभ्यास अधिक प्रासंगिक क्यों है? आपके द्वारा उल्लिखित लाभ OO प्रोग्रामिंग में भी देखे जा सकते हैं, है ना?
राहुलगा_देव

OO में आप ऑब्जेक्ट की अपेक्षा करेंगे। Purchase () ऑब्जेक्ट को संशोधित करने के लिए। आप इसे अपरिवर्तनीय बना सकते हैं, लेकिन फिर एक पूर्ण कार्यात्मक प्रतिमान पर क्यों नहीं जाएं
इवान

मुझे लगता है कि समस्या की कल्पना की जा रही है क्योंकि मैं शुद्ध सी # डेवलपर हूं जो प्रकृति द्वारा वस्तु उन्मुख है। तो आप जो भाषा में कह रहे हैं, जो कार्यात्मक प्रोग्रामिंग को गले लगाती है, उसे किसी भी वर्ग या वस्तु के साथ संलग्न होने के लिए खरीदे गए ऑर्डर को 'खरीद ()' की आवश्यकता नहीं होगी, है ना?
rahulaga_dev

3
आप कार्यात्मक सी # अपनी वस्तु को एक संरचना में बदल सकते हैं, इसे अपरिवर्तनीय बना सकते हैं और एक फंक लिख सकते हैं <ऑर्डर, ऑर्डर> खरीद
इवान

12

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

मुख्य बात यह है कि अपरिवर्तनीयता का वह लाभ क्या है? जवाब है, यह जटिलता से बचा जाता है। कहें कि हमारे पास दो चर हैं, xऔर y। दोनों के मूल्य से शुरू होते हैं 1yहालांकि हर 13 सेकंड में दोगुना हो जाता है। 20 दिनों के समय में उनमें से प्रत्येक का मूल्य क्या होगा? xहो जाएगा 1। यह आसान है। हालांकि yयह अधिक जटिल है क्योंकि यह काम करने के लिए प्रयास करेगा । 20 दिनों के समय में दिन का क्या समय? क्या मुझे दिन की बचत को ध्यान में रखना है? yबनाम की जटिलता xबस इतनी अधिक है।

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

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


4
"जटिलता को कम करने के सबसे सरल तरीकों में से एक चीज़ों को डिफ़ॉल्ट रूप से अपरिवर्तनीय बनाना और केवल ज़रूरत पड़ने पर उन्हें परिवर्तनशील बनाना है": बहुत अच्छा और संक्षिप्त सारांश।
जियोर्जियो

2
@DavidArno आप जिस जटिलता का वर्णन करते हैं वह कोड को तर्क के लिए कठिन बनाता है। जब आप कहते हैं कि आपने "इस कोड को लिखना मुश्किल है, पढ़ना मुश्किल है, तो डिबग करना मुश्किल है ..."। मैं अपरिवर्तनीय वस्तुओं को पसंद करता हूं, क्योंकि वे कोड को बहुत आसान बना देते हैं, न केवल खुद के बारे में, बल्कि पर्यवेक्षकों को जो पूरी परियोजना को जाने बिना देखते हैं।
असंतुष्ट-संख्या -5

1
@RahulAgarwal, " लेकिन कार्यात्मक प्रोग्रामिंग के संदर्भ में यह समस्या अधिक प्रमुख क्यों है "। यह नहीं है मुझे लगता है कि शायद मैं भ्रमित हूं कि आप क्या पूछ रहे हैं क्योंकि एफपी में समस्या काफी कम है क्योंकि एफपी अपरिवर्तनीयता को प्रोत्साहित करता है और इस प्रकार समस्या से बचा जाता है।
डेविड अरनो

1
@djechlin, " कैसे अपने 13 दूसरा उदाहरण आसान हो सकता है अपरिवर्तनीय कोड के साथ विश्लेषण करने के लिए? " यह नहीं कर सकते: yउत्परिवर्तन है; यह एक आवश्यकता है। कभी-कभी हमें जटिल आवश्यकताओं को पूरा करने के लिए जटिल कोड रखना पड़ता है। मैं जिस बिंदु को बनाने की कोशिश कर रहा था वह यह है कि अनावश्यक जटिलता से बचा जाना चाहिए। उत्परिवर्तन मान निश्चित रूप से निश्चित की तुलना में अधिक जटिल होते हैं, इसलिए - अनावश्यक जटिलता से बचने के लिए - केवल तब ही म्यूट करें जब आपको करना है।
डेविड अरनो

3
उत्परिवर्तन एक पहचान संकट पैदा करता है। आपके चर की अब एक भी पहचान नहीं है। इसके बजाय, इसकी पहचान अब समय पर निर्भर करती है। इसलिए प्रतीकात्मक रूप से, एकल x के बजाय, अब हमारे पास एक परिवार x_t है। उस चर का उपयोग करने वाले किसी भी कोड को अब समय के साथ-साथ चिंता करनी होगी, जिससे उत्तर में अतिरिक्त जटिलता का उल्लेख किया जा सकेगा।
एलेक्स वोंग

8

कार्यात्मक प्रोग्रामिंग के संदर्भ में क्या गलत हो सकता है

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

कार्यात्मक और गैर-कार्यात्मक प्रोग्रामिंग के बीच इस पर IMHO एकमात्र वास्तविक अंतर है, गैर-कार्यात्मक कोड में आप आमतौर पर कार्यात्मक प्रोग्रामिंग में साइड-इफेक्ट्स की उम्मीद करेंगे, आप नहीं करेंगे।

मूल रूप से अगर यह खराब है, तो यह ओओ या कार्यात्मक प्रोग्रामिंग प्रतिमान के बावजूद बुरा है, है ना?

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


4

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

for (elem <- rows map (row => s3 map row)) {
  val elem_str = elem.map(_.toString)

  logger.info("verifying the S3 bucket passed from the ctrl table for each App")
  logger.info(s"Checking on App Code: ${elem head}")

  listS3Buckets(elem_str(1), elem_str(2)) match {

    case Some(allBktsInfo) =>
      logger.info(s"App: ${elem_str head} provided the bucket name as: ${elem_str(3)}")
      if (allBktsInfo.exists(x => x.getName == elem_str(3))) {
        logger.info(s"Provided S3 bucket: ${elem_str(3)} exists")
        println(s"s3 ${elem_str(3)} bucket exists")
      } else {
        logger.info(s"WARNING: Provided S3 bucket ${elem_str(3)} doesn't exists")
        logger.info(s"WARNING: Dropping the App: ${elem_str.head} from backup schedule")
        excludeList += elem_str.head // If the bucket is invalid then we exclude from backup
        println(s"s3 bucket ${elem_str(3)} doesn't exists")
    }

    case None =>
      logger.info(s"WARNING: Provided S3 bucket ${elem_str(3)} doesn't exists")
      logger.info(s"WARNING: Dropping the App: ${elem_str.head} from backup schedule")
      excludeList += elem_str.head // If the bucket is invalid then we exclude from backup
}

जब आप अपरिवर्तनीयता के आदी हो जाते हैं, तो डेटा संरचना के बदलने का कोई डर नहीं है यदि आप बहुत लंबे समय तक प्रतीक्षा करते हैं, तो आप ऐसे कार्य कर सकते हैं जो तार्किक रूप से आपके अवकाश में अलग हैं, बहुत अधिक डिकोड किए गए तरीके से:

val (exists, missing) = rows partition bucketExists
missing foreach {row =>
  logger.info(s"WARNING: Provided S3 bucket ${row("s3_primary_bkt_name")} doesn't exist")
  logger.info(s"WARNING: Dropping the App: ${row("app")} from backup schedule")
}

3

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

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

मुझे लगता है कि यह सबसे उपयोगी है, सामान्य रूप से प्रोग्रामिंग के लिए (न कि केवल कार्यात्मक प्रोग्रामिंग) अपरिवर्तनीय वस्तुओं को तीन श्रेणियों में गिरने के बारे में सोचने के लिए:

  1. ऐसी वस्तुएँ जो किसी भी चीज़ को संदर्भ के साथ बदलने की अनुमति नहीं दे सकती हैं। ऐसी वस्तुएं, और उनके संदर्भ, मूल्यों के रूप में व्यवहार करते हैं , और स्वतंत्र रूप से साझा किए जा सकते हैं।

  2. ऐसी वस्तुएँ जो स्वयं को उन कोडों द्वारा परिवर्तित करने की अनुमति देती हैं जिनके संदर्भ उनके पास हैं, लेकिन जिनके संदर्भ कभी भी किसी भी कोड के संपर्क में नहीं आएंगे जो वास्तव में उन्हें बदल देगा । ये ऑब्जेक्ट मानों को एनकैप्सुलेट करते हैं, लेकिन उन्हें केवल उन कोड के साथ साझा किया जा सकता है, जिन पर भरोसा किया जा सकता है कि वे उन्हें नहीं बदल सकते हैं या कोड को उजागर नहीं कर सकते हैं।

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

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

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


प्रभावशाली उत्तर के लिए धन्यवाद !! मुझे लगता है कि शायद मेरी उलझन का स्रोत c # बैकग्राउंड से है और मैं "c # में फंक्शनल स्टाइल कोड लिखना सीख रहा हूं" जो हर जगह यह कहता रहता है कि उत्परिवर्तित वस्तुओं से बचें - लेकिन मुझे लगता है कि जो भाषाएं कार्यात्मक प्रोग्रामिंग प्रतिमान को बढ़ावा देती हैं (या लागू करती हैं - निश्चित नहीं हैं) यदि प्रवर्तन क्षमता का उपयोग करने के लिए सही है)।
रहलगा_देव

@RahulAgarwal: यह एक वस्तु Encapsulate एक के लिए संदर्भ के लिए संभव है मूल्य , जिसका अर्थ एक ही वस्तु को अन्य संदर्भ के अस्तित्व से अप्रभावित है एक है पहचान है जो एक ही वस्तु या न करने के लिए अन्य संदर्भों के साथ उन्हें संबद्ध कर देते। यदि वास्तविक-शब्द की स्थिति बदलती है, तो या तो उस राज्य से जुड़ी किसी वस्तु का मूल्य या पहचान स्थिर हो सकती है, लेकिन दोनों नहीं - एक को बदलना होगा। $ 50,000 जो है उसे करना चाहिए।
सुपरकैट

1

जैसा कि पहले ही उल्लेख किया गया है, उत्परिवर्ती राज्य के साथ समस्या मूल रूप से साइड इफेक्ट की बड़ी समस्या का एक उपवर्ग है , जहां एक फ़ंक्शन का रिटर्न-प्रकार सही ढंग से वर्णन नहीं करता है कि फ़ंक्शन वास्तव में क्या करता है, क्योंकि इस मामले में, यह राज्य उत्परिवर्तन भी करता है। इस समस्या को कुछ नई शोध भाषाओं ने संबोधित किया है, जैसे कि एफ * ( http://www.fstar-lang.org/tutorial/ )। यह भाषा एक प्रकार की प्रणाली के समान एक इफेक्ट सिस्टम बनाती है, जहाँ एक फ़ंक्शन न केवल स्टेटिक रूप से अपने प्रकार की घोषणा करता है, बल्कि इसके प्रभाव भी। इस तरह, फ़ंक्शन के कॉल करने वाले जानते हैं कि फ़ंक्शन को कॉल करते समय राज्य उत्परिवर्तन हो सकता है, और यह प्रभाव इसके कॉलर्स के लिए प्रचारित किया जाता है।

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