सीमांकित निरंतरता

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

इतिहास
सीमांकित निरंतरताओं को पहली बार 1988 में फेलिसेन द्वारा एक ऑपरेटर के साथ प्रस्तुत किया गया था, $$\mathcal{F}$$ पहली बार 1987 में एक तकनीकी रिपोर्ट में पेश किया गया था, एक त्वरित निर्माण के साथ $$\#$$ ऑपरेटर को उन नियंत्रण ऑपरेटरों के सामान्यीकरण के लिए डिज़ाइन किया गया था जिनका वर्णन साहित्य में किया गया था जैसे स्कीम से , ISWIM के J ऑपरेटर, जॉन सी. रेनॉल्ड्स'  ऑपरेटर, और अन्य है। इसके बाद, प्रोग्रामिंग भाषाओं के अनुसंधान समुदाय द्वारा कई प्रतिस्पर्धी सीमांकित नियंत्रण ऑपरेटरों का आविष्कार किया गया   और ,   और  ,  ,  , और दूसरे अन्य है।

उदाहरण
शोध साहित्य में सीमांकित निरंतरता के लिए विभिन्न ऑपरेटरों का प्रस्ताव किया गया है।

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

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

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

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

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

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

जो इस उदाहरण को और अधिक जटिल बनाते है: यदि हम सबसे पहले टिप्पणी करें करते हैं, तो हम पहले से ही परिणाम जानते हैं, यह है ; इसलिए हम इस प्रकार अभिव्यक्ति को फिर से लिख सकते हैं: यह काफी परिचित है, और इसे इस रूप में फिर से लिखा जा सकता है, वह है,.

हम इस ट्रिक का उपयोग करके को परिभाषित कर सकते हैं:

(define (yield x) (shift k (cons x (k (void)))))

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

भाषाशास्त्र में सीमांकित निरंतरताएँ भी उपयोगी हैं: विवरण के लिए भाषाशास्त्र में निरंतरताएँ देखें।

बाहरी संबंध

 * Composable continuations tutorial at SchemeWiki
 * Delimited continuations in operating systems, by Oleg Kiselyov and Chung-chieh Shan
 * Native delimited continuations in (byte-code and native-code) OCaml
 * Shift/reset для самых маленьких
 * Some nice papers on delimited continuations and first-class macros