सीमांकित निरंतरता: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
 
(3 intermediate revisions by 3 users not shown)
Line 3: Line 3:
== इतिहास ==
== इतिहास ==


सीमांकित निरंतरताओं को पहली बार 1988 में फेलिसेन द्वारा एक ऑपरेटर के साथ प्रस्तुत किया गया था,<ref name='felleisen88'/>  <math>\mathcal{F}</math> पहली बार 1987 में एक तकनीकी रिपोर्ट में पेश किया गया था,<ref name='felleisen 87 tr'/> एक त्वरित निर्माण के साथ <math>\#</math> ऑपरेटर को उन नियंत्रण ऑपरेटरों के सामान्यीकरण के लिए डिज़ाइन किया गया था जिनका वर्णन साहित्य में किया गया था जैसे स्कीम से <code>call/cc</code>, [[ISWIM]] के [[Index.php?title=J ऑपरेटर|J ऑपरेटर]], जॉन सी. रेनॉल्ड्स' <code>escape</code> ऑपरेटर, और अन्य है। इसके बाद, प्रोग्रामिंग भाषाओं के अनुसंधान समुदाय द्वारा कई प्रतिस्पर्धी सीमांकित नियंत्रण ऑपरेटरों का आविष्कार किया गया <code>prompt</code> और <code>control</code>,<ref>{{cite journal|url=http://www.ccs.neu.edu/racket/pubs/lasc1990-sf.pdf|last1=Sitaram|first1=Dorai|last2=Felleisen|first2=Matthias|title=सीमांकक और उनके पदानुक्रम को नियंत्रित करें|journal=Lisp and Symbolic Computation|year=1990|volume=3|pages=67–99|doi=10.1007/BF01806126|s2cid=31430221 }}</ref> <code>shift</code> और <code>reset</code>,<ref name="danvy90">{{cite conference|title=सार नियंत्रण|last1=Danvy|first1=Olivier |last2=Filinski|first2=Andrzej|book-title=LISP and Functional Programming|year=1990|pages=151–160|isbn=0-89791-368-X|doi=10.1145/91556.91622|s2cid=6426191|doi-access=free }}</ref><ref name='danvy06'>{{cite thesis|title=डेटा ऑब्जेक्ट के रूप में प्रोग्राम के लिए एक विश्लेषणात्मक दृष्टिकोण|author=Danvy, Olivier|url=https://ebooks.au.dk/index.php/aul/catalog/book/214|year=2006|doi=10.7146/aul.214.152}}</ref><code>cupto</code>,<ref name='gunter95'>{{cite conference|title=एमएल जैसी भाषाओं में अपवादों और नियंत्रण का सामान्यीकरण|author1=Rémy, Didier|author2=Gunter, Carl|author3=Riecke, Jon G.|book-title=Functional Programming Language and Computer Architecture|year=1995}}</ref> <code>fcontrol</code>, और दूसरे अन्य है।
सीमांकित निरंतरताओं को पहली बार 1988 में फेलिसेन द्वारा एक ऑपरेटर के साथ प्रस्तुत किया गया था,<ref name='felleisen88'/>  <math>\mathcal{F}</math> पहली बार 1987 में एक तकनीकी रिपोर्ट में प्रस्तुत किया गया था,<ref name='felleisen 87 tr'/> एक त्वरित निर्माण के साथ <math>\#</math> ऑपरेटर को उन नियंत्रण ऑपरेटरों के सामान्यीकरण के लिए डिज़ाइन किया गया था जिनका वर्णन साहित्य में किया गया था जैसे स्कीम से <code>call/cc</code>, [[ISWIM]] के [[Index.php?title=J ऑपरेटर|J ऑपरेटर]], जॉन सी. रेनॉल्ड्स' <code>escape</code> ऑपरेटर, और अन्य है। इसके बाद, प्रोग्रामिंग लैंग्वेजेज के अनुसंधान समुदाय द्वारा कई प्रतिस्पर्धी सीमांकित नियंत्रण ऑपरेटरों का आविष्कार किया गया <code>prompt</code> और <code>control</code>,<ref>{{cite journal|url=http://www.ccs.neu.edu/racket/pubs/lasc1990-sf.pdf|last1=Sitaram|first1=Dorai|last2=Felleisen|first2=Matthias|title=सीमांकक और उनके पदानुक्रम को नियंत्रित करें|journal=Lisp and Symbolic Computation|year=1990|volume=3|pages=67–99|doi=10.1007/BF01806126|s2cid=31430221 }}</ref> <code>shift</code> और <code>reset</code>,<ref name="danvy90">{{cite conference|title=सार नियंत्रण|last1=Danvy|first1=Olivier |last2=Filinski|first2=Andrzej|book-title=LISP and Functional Programming|year=1990|pages=151–160|isbn=0-89791-368-X|doi=10.1145/91556.91622|s2cid=6426191|doi-access=free }}</ref><ref name='danvy06'>{{cite thesis|title=डेटा ऑब्जेक्ट के रूप में प्रोग्राम के लिए एक विश्लेषणात्मक दृष्टिकोण|author=Danvy, Olivier|url=https://ebooks.au.dk/index.php/aul/catalog/book/214|year=2006|doi=10.7146/aul.214.152}}</ref><code>cupto</code>,<ref name='gunter95'>{{cite conference|title=एमएल जैसी भाषाओं में अपवादों और नियंत्रण का सामान्यीकरण|author1=Rémy, Didier|author2=Gunter, Carl|author3=Riecke, Jon G.|book-title=Functional Programming Language and Computer Architecture|year=1995}}</ref> <code>fcontrol</code>, और दूसरे अन्य है।


== उदाहरण ==
== उदाहरण ==
शोध साहित्य में सीमांकित निरंतरता के लिए विभिन्न ऑपरेटरों का प्रस्ताव किया गया है।<ref name="Ref_">उदाहरण के लिए, द्वारा प्रस्तावित ऑपरेटरों को देखें <code>racket/control</code> [[रैकेट (प्रोग्रामिंग भाषा)]] लाइब्रेरी [http://docs.racket-lang.org/reference/cont.html#(part._.Classical_.Control_.Operators)]; निम्नलिखित उदाहरणों का उपयोग करके रैकेट में चलाया जा सकता है <code>(require racket/control)</code></ref>
शोध साहित्य में सीमांकित निरंतरता के लिए विभिन्न ऑपरेटरों का प्रस्ताव किया गया है।<ref name="Ref_">उदाहरण के लिए, द्वारा प्रस्तावित ऑपरेटरों को देखें <code>racket/control</code> [[रैकेट (प्रोग्रामिंग भाषा)]] लाइब्रेरी [http://docs.racket-lang.org/reference/cont.html#(part._.Classical_.Control_.Operators)]; निम्नलिखित उदाहरणों का उपयोग करके रैकेट में चलाया जा सकता है <code>(require racket/control)</code></ref>


एक स्वतंत्र प्रस्ताव<ref name='danvy90'/>निरंतरता-पासिंग शैली (सीपीएस) पर आधारित है - अर्थात, निरंतरता फ़्रेम पर नहीं - और दो नियंत्रण ऑपरेटर प्रदान करता है, <code>shift</code> और <code>reset</code>, जो गतिशील सीमांकित निरंतरताओं के बजाय स्थैतिक को जन्म देता है।<ref name="biernacki et al scp-06">
एक स्वतंत्र प्रस्ताव<ref name='danvy90'/>निरंतरता-पासिंग शैली (CPS) पर आधारित है - अर्थात, निरंतरता फ़्रेम पर नहीं - और दो नियंत्रण ऑपरेटर प्रदान करता है, <code>shift</code> और <code>reset</code>, जो गतिशील सीमांकित निरंतरताओं के अतिरिक्त स्थैतिक को जन्म देता है।<ref name="biernacki et al scp-06">
{{cite journal
{{cite journal
|last1=Biernacki
|last1=Biernacki
Line 24: Line 24:
|url=https://tidsskrift.dk/brics/article/download/21903/19329/}}
|url=https://tidsskrift.dk/brics/article/download/21903/19329/}}
</ref>
</ref>
  <code>रीसेट</code>ऑपरेटर निरंतरता के लिए सीमा निर्धारित करता है जबकि <code>shift</code> ऑपरेटर वर्तमान निरंतरता को अंतरतम परिक्षेत्र तक पकड़ता है या उसका पुनरीक्षण करता है <code>reset</code>. उदाहरण के लिए, निम्नलिखित स्निपेट पर विचार करें:  
  <code>रीसेट</code>ऑपरेटर निरंतरता के लिए सीमा निर्धारित करता है जबकि <code>shift</code> ऑपरेटर वर्तमान निरंतरता को अंतरतम परिक्षेत्र तक कैच है या उसका पुनरीक्षण करता है।  


<syntaxhighlight lang="scheme">(* 2 (reset (+ 1 (shift k (k 5)))))</syntaxhighlight>
<syntaxhighlight lang="scheme">(* 2 (reset (+ 1 (shift k (k 5)))))</syntaxhighlight>


  <code>रीसेट</code>उस निरंतरता का परिसीमन करता है जो<code>शिफ्ट</code> कैप्चर करता है। जब यह स्निपेट निष्पादित किया जाता है, तो इसका उपयोग होता है तो<code>शिफ्ट</code> का उपयोग <code>k</code> को निरंतरता <code>(+ 1 [])</code> से बांध देगा जहां <code>[]</code> गणना के उस हिस्से का प्रतिनिधित्व करता है जिसे एक मूल्य से भरा जाना है। यह निरंतरता सीधे उस कोड से मेल खाती है जो रीसेट तक शिफ्ट को घेरता है। क्योंकि शिफ्ट का मुख्य भाग (यानी, (k 5)) तुरंत निरंतरता का आह्वान करता है, यह कोड निम्नलिखित के बराबर है:   
  <code>रीसेट</code>उस निरंतरता का परिसीमन करता है जो<code>shift</code>कैप्चर करता है। जब यह स्निपेट निष्पादित किया जाता है, तो इसका उपयोग होता है<code>शिफ्ट</code>का उपयोग<code>k</code>को निरंतरता<code>(+ 1 [])</code>से बांध देगा जहां<code>[]</code>गणना के उस हिस्से का प्रतिनिधित्व करता है जिसे एक मूल्य से भरा जाना है। यह निरंतरता सीधे उस कोड से मेल खाती है जो<code>reset</code>तक<code>shift</code>को घेरता है। चूंकि<code>shift</code>का मुख्य भाग (अर्थात्, (k 5)) तुरंत निरंतरता की स्तुति करता है:   


<syntaxhighlight lang="scheme">(* 2 (+ 1 5))</syntaxhighlight>
<syntaxhighlight lang="scheme">(* 2 (+ 1 5))</syntaxhighlight>
सामान्य तौर पर, ये ऑपरेटर अधिक दिलचस्प व्यवहार को एनकोड कर सकते हैं, उदाहरण के लिए, कैप्चर की गई निरंतरता <code>k</code> को एक मान के रूप में वापस करना या <code>k</code> को कई बार लागू करना है। शिफ्ट ऑपरेटर कैप्चर की गई निरंतरता को पास करता है <code>k</code> इसके मुख्य भाग में कोड के लिए, जो या तो इसे लागू कर सकता है, इसके परिणामस्वरूप इसे उत्पन्न कर सकता है, या इसे पूरी तरह से अनदेखा कर सकता है। जो भी परिणाम शिफ्ट उत्पन्न करता है वह रीसेट और शिफ्ट के बीच की निरंतरता को छोड़कर, अंतरतम रीसेट को प्रदान किया जाता है। हालाँकि, यदि निरंतरता लागू की जाती है, तो यह रीसेट पर लौटने के बाद निरंतरता को प्रभावी ढंग से पुनः स्थापित करता है। जब रीसेट के भीतर संपूर्ण गणना पूरी हो जाती है, तो परिणाम सीमांकित निरंतरता द्वारा लौटाया जाता है।<ref name="final-shift">{{cite conference|author1=Gasbichler, Martin|author2=Sperber, Michael|book-title=International Conference on Functional Programming|year=2002|citeseerx = 10.1.1.11.3425 }}</ref>   
सामान्य तौर पर, ये ऑपरेटर अधिक , रोचक व्यवहार को एनकोड कर सकते हैं, उदाहरण के लिए, कैप्चर की गई निरंतरता <code>k</code> को एक मान के रूप में वापस करना या <code>k</code> को कई बार लागू करना है।<code>shift</code> ऑपरेटर कैप्चर की गई निरंतरता को पास करता है <code>k</code> इसके मुख्य भाग में कोड के लिए, जो या तो इसे लागू कर सकता है, या इसके परिणामस्वरूप इसे उत्पन्न कर सकता है, या इसे पूरी तरह से अनदेखा कर सकता है। जो भी परिणाम <code>shift</code> उत्पन्न करता है वह <code>reset</code> और <code>shift</code> के बीच की निरंतरता को छोड़कर, अंतरतम <code>reset</code> को प्रदान किया जाता है। चूंकि, यदि निरंतरता लागू की जाती है, तो यह <code>reset</code> पर लौटने के बाद निरंतरता को प्रभावी ढंग से पुनः स्थापित करता है। जब <code>reset</code> के अन्दर संपूर्ण गणना पूरी हो जाती है, तो परिणाम सीमांकित निरंतरता द्वारा लौटाया जाता है।<ref name="final-shift">{{cite conference|author1=Gasbichler, Martin|author2=Sperber, Michael|book-title=International Conference on Functional Programming|year=2002|citeseerx = 10.1.1.11.3425 }}</ref>   
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
  (reset (* 2 (shift k CODE)))
  (reset (* 2 (shift k CODE)))
Line 41: Line 41:
   (let ((k (lambda (x) (* 2 x)))) CODE)
   (let ((k (lambda (x) (* 2 x)))) CODE)
</syntaxhighlight>
</syntaxhighlight>
इसके अलावा, एक बार शिफ्ट के भीतर पूरी गणना पूरी हो जाने के बाद, निरंतरता को हटा दिया जाता है, और निष्पादन रीसेट पुनः आरंभ होता है।  
इसके अतिरिक्त, एक बार <code>shift</code> के अन्दर गणना पूरी हो जाने के बाद, निरंतरता को हटा दिया जाता है, और निष्पादन <code>reset</code> पुनः आरंभ होता है।  
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
  (reset (* 2 (shift k (k (k 4)))))</syntaxhighlight>
  (reset (* 2 (shift k (k (k 4)))))</syntaxhighlight>
पहले <code>(k 4)</code> को आमंत्रित करता है (जो 8 लौटाता है), और फिर <code>(k 8)</code> (जो 16 लौटाता है)। इस बिंदु पर, <code>शिफ्ट</code> अभिव्यक्ति समाप्त हो गई है, और शेष <code>रीसेट</code> अभिव्यक्ति को छोड़ दिया गया है। इसलिए, अंतिम परिणाम 16 है।
पहले <code>(k 4)</code> को आमंत्रित करता है, और फिर<code>(k 8)</code>इस बिंदु पर, <code>shift</code>अभिव्यक्ति समाप्त हो गई है, और शेष <code>reset</code>अभिव्यक्ति को छोड़ दिया गया है। इसलिए, अंतिम परिणाम 16 है।


<code>रीसेट</code>  अभिव्यक्ति के बाहर जो कुछ भी होता है वह छिपा हुआ होता है, यानी नियंत्रण हस्तांतरण से प्रभावित नहीं होता है। उदाहरण के लिए, यह 17 लौटाता है:
<code>reset</code>  अभिव्यक्ति के बाहर जो कुछ भी होता है वह छिपा हुआ होता है, यानी नियंत्रण हस्तांतरण से प्रभावित नहीं होता है।
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
  (+ 1 (reset (* 2 (shift k (k (k 4))))))</syntaxhighlight>
  (+ 1 (reset (* 2 (shift k (k (k 4))))))</syntaxhighlight>
Line 57: Line 57:
     (shift k (cons 1 (k (void)))) ;; (1)
     (shift k (cons 1 (k (void)))) ;; (1)
     null))</syntaxhighlight>
     null))</syntaxhighlight>
<code>शिफ्ट</code> द्वारा कैप्चर किया गया संदर्भ<code>(begin [*] null)</code>  है, जहां <code>[*]</code> वह छेद है जहाँ <code>k</code>का पैरामीटर इंजेक्ट किया जाएगा है। <code>shift</code> के अंदर <code>k</code> इस संदर्भ का मूल्यांकन करता है <code>(void)</code> = <code>#<void></code> छेद को प्रतिस्थापित करने के साथ मूल्यांकन करती है, इसलिए<code>(k (void))</code> का मान<code>(begin #<void> null)</code> = <code>null है।</code> <code>shift</code>  का मुख्य भाग, अर्थात् <code>(cons 1 null)</code> = <code>(1)</code>, अंतिम परिणाम के रूप में <code>reset</code> अभिव्यक्ति का समग्र मूल्य बन जाता है।
<code>shift</code> द्वारा कैप्चर किया गया संदर्भ<code>(begin [*] null)</code>  है, जहां <code>[*]</code> वह है <code>k</code>का पैरामीटर इंजेक्ट किया जाता है। <code>shift</code> के अंदर <code>k</code> इस संदर्भ का मूल्यांकन करता है <code>(void)</code> = <code>#<void></code> को प्रतिस्थापित करने के साथ मूल्यांकन करती है, इसलिए<code>(k (void))</code> का मान<code>(begin #<void> null)</code> = <code>null है।</code> <code>shift</code>  का मुख्य भाग, अर्थात् <code>(cons 1 null)</code> = <code>(1)</code>, अंतिम परिणाम के रूप में <code>reset</code> अभिव्यक्ति का समग्र मूल्य बन जाता है।


जो इस उदाहरण को और अधिक जटिल बनाते है:  
जो इस उदाहरण को और अधिक जटिल बनाते है:  
Line 72: Line 72:
     (shift k (cons 1 (k (void))))
     (shift k (cons 1 (k (void))))
     (list 2)))</syntaxhighlight>
     (list 2)))</syntaxhighlight>
यह काफी परिचित है, और इसे इस रूप में फिर से लिखा जा सकता है <code>(cons 1 (list 2))</code>, वह है, <code>(list 1 2)</code>.
यह उचित है, और इसे इस रूप में फिर से लिखा जा सकता है <code>(cons 1 (list 2))</code>,<code>(list 1 2)</code>.


हम इस ट्रिक का उपयोग करके<code>yield</code> को परिभाषित कर सकते हैं:
हम इस ट्रिक का उपयोग करके<code>yield</code> को परिभाषित कर सकते हैं:
Line 85: Line 85:
           (yield 3)
           (yield 3)
           null))    ;; (list 1 2 3)</syntaxhighlight>
           null))    ;; (list 1 2 3)</syntaxhighlight>
यदि हम <code>cons</code> को <code>stream-cons</code> से प्रतिस्थापित करते हैं, तो हम आलसी स्ट्रीम बना सकते हैं:  
यदि हम <code>cons</code> को <code>stream-cons</code> से प्रतिस्थापित करते हैं, तो हम मंद स्ट्रीम बना सकते हैं:  
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
   (define (stream-yield x) (shift k (stream-cons x (k (void)))))
   (define (stream-yield x) (shift k (stream-cons x (k (void)))))
Line 96: Line 96:
             stream-null)))
             stream-null)))
</syntaxhighlight>
</syntaxhighlight>
हम इसे सामान्यीकृत कर सकते हैं और सूचियों को एक झटके में स्ट्रीम में परिवर्तित कर सकते हैं:  
हम इसे सामान्यीकृत कर सकते हैं और सूचियों को स्ट्रीम में परिवर्तित कर सकते हैं:  
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
  (define (list->stream xs)
  (define (list->stream xs)
Line 103: Line 103:
             stream-null)))
             stream-null)))
</syntaxhighlight>
</syntaxhighlight>
नीचे दिए गए अधिक जटिल उदाहरण में निरंतरता को लैम्ब्डा के शरीर में सुरक्षित रूप से लपेटा जा सकता है, और इस प्रकार उपयोग किया जा सकता है:  
नीचे दिए गए अधिक जटिल उदाहरण में निरंतरता को लैम्ब्डा में सुरक्षित रूप से रखा जा सकता है, और इस प्रकार उपयोग किया जा सकता है:  
<syntaxhighlight lang="scheme">
<syntaxhighlight lang="scheme">
  (define (for-each->stream-maker for-each)  
  (define (for-each->stream-maker for-each)  
Line 114: Line 114:
               stream-null))))
               stream-null))))
</syntaxhighlight>
</syntaxhighlight>
<code>reset</code> और <code>shift</code> के बीच के हिस्से में <code>lambda</code> और <code>for-each</code> के लिए नियंत्रण कार्य शामिल हैं; लैम्ब्डा का उपयोग करके इसे दोबारा लिखना असंभव है{{why?|date=August 2012}}.
<code>reset</code> और <code>shift</code> के बीच के हिस्से में <code>lambda</code> और <code>for-each</code> के लिए नियंत्रण कार्य सम्मलित हैं; लैम्ब्डा का उपयोग करके इसे दोबारा लिखना असंभव है{{why?|date=August 2012}}.


[[भाषाशास्त्र]] में सीमांकित निरंतरताएँ भी उपयोगी हैं: विवरण के लिए [[भाषाशास्त्र में निरंतरताएँ]] देखें।
[[भाषाशास्त्र]] में सीमांकित निरंतरताएँ भी उपयोगी हैं: विवरण के लिए [[भाषाशास्त्र में निरंतरताएँ]] देखें।
Line 129: Line 129:
*[http://axisofeval.blogspot.com/2011/07/some-nice-paperz.html Some nice papers on delimited continuations and first-class macros]
*[http://axisofeval.blogspot.com/2011/07/some-nice-paperz.html Some nice papers on delimited continuations and first-class macros]


{{DEFAULTSORT:Delimited Continuation}}[[Category: बहाव को काबू करें]] [[Category: निरंतरता]] [[Category: रैकेट कोड उदाहरण सहित लेख]]
{{DEFAULTSORT:Delimited Continuation}}


 
[[Category:Articles with Russian-language sources (ru)|Delimited Continuation]]
 
[[Category:Created On 11/07/2023|Delimited Continuation]]
[[Category: Machine Translated Page]]
[[Category:Machine Translated Page|Delimited Continuation]]
[[Category:Created On 11/07/2023]]
[[Category:Pages with script errors|Delimited Continuation]]
[[Category:Templates Vigyan Ready]]
[[Category:Wikipedia articles needing clarification from August 2012|Delimited Continuation]]
[[Category:निरंतरता|Delimited Continuation]]
[[Category:बहाव को काबू करें|Delimited Continuation]]
[[Category:रैकेट कोड उदाहरण सहित लेख|Delimited Continuation]]

Latest revision as of 16:27, 26 July 2023

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

इतिहास

सीमांकित निरंतरताओं को पहली बार 1988 में फेलिसेन द्वारा एक ऑपरेटर के साथ प्रस्तुत किया गया था,[1] पहली बार 1987 में एक तकनीकी रिपोर्ट में प्रस्तुत किया गया था,[2] एक त्वरित निर्माण के साथ ऑपरेटर को उन नियंत्रण ऑपरेटरों के सामान्यीकरण के लिए डिज़ाइन किया गया था जिनका वर्णन साहित्य में किया गया था जैसे स्कीम से call/cc, ISWIM के J ऑपरेटर, जॉन सी. रेनॉल्ड्स' escape ऑपरेटर, और अन्य है। इसके बाद, प्रोग्रामिंग लैंग्वेजेज के अनुसंधान समुदाय द्वारा कई प्रतिस्पर्धी सीमांकित नियंत्रण ऑपरेटरों का आविष्कार किया गया prompt और control,[4] shift और reset,[5][6]cupto,[7] fcontrol, और दूसरे अन्य है।

उदाहरण

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

एक स्वतंत्र प्रस्ताव[5]निरंतरता-पासिंग शैली (CPS) पर आधारित है - अर्थात, निरंतरता फ़्रेम पर नहीं - और दो नियंत्रण ऑपरेटर प्रदान करता है, shift और reset, जो गतिशील सीमांकित निरंतरताओं के अतिरिक्त स्थैतिक को जन्म देता है।[9]

रीसेटऑपरेटर निरंतरता के लिए सीमा निर्धारित करता है जबकि shift ऑपरेटर वर्तमान निरंतरता को अंतरतम परिक्षेत्र तक कैच है या उसका पुनरीक्षण करता है।  
(* 2 (reset (+ 1 (shift k (k 5)))))
रीसेटउस निरंतरता का परिसीमन करता है जोshiftकैप्चर करता है। जब यह स्निपेट निष्पादित किया जाता है, तो इसका उपयोग होता हैशिफ्टका उपयोगkको निरंतरता(+ 1 [])से बांध देगा जहां[]गणना के उस हिस्से का प्रतिनिधित्व करता है जिसे एक मूल्य से भरा जाना है। यह निरंतरता सीधे उस कोड से मेल खाती है जोresetतकshiftको घेरता है। चूंकिshiftका मुख्य भाग (अर्थात्, (k 5)) तुरंत निरंतरता की स्तुति करता  है:  
(* 2 (+ 1 5))

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

 (reset (* 2 (shift k CODE)))

जब कभी भी CODE (k N) को आमंत्रित करता है, * 2 N) का मूल्यांकन किया जाता है और वापस कर दिया जाता है।

यह निम्नलिखित के बराबर है:

  (let ((k (lambda (x) (* 2 x)))) CODE)

इसके अतिरिक्त, एक बार shift के अन्दर गणना पूरी हो जाने के बाद, निरंतरता को हटा दिया जाता है, और निष्पादन reset पुनः आरंभ होता है।

 (reset (* 2 (shift k (k (k 4)))))

पहले (k 4) को आमंत्रित करता है, और फिर(k 8)इस बिंदु पर, shiftअभिव्यक्ति समाप्त हो गई है, और शेष resetअभिव्यक्ति को छोड़ दिया गया है। इसलिए, अंतिम परिणाम 16 है।

reset अभिव्यक्ति के बाहर जो कुछ भी होता है वह छिपा हुआ होता है, यानी नियंत्रण हस्तांतरण से प्रभावित नहीं होता है।

 (+ 1 (reset (* 2 (shift k (k (k 4))))))

सीमांकित निरंतरताओं का वर्णन सबसे पहले फ़ेलिसेन एट अल द्वारा स्वतंत्र रूप से किया गया था।[2] और जॉनसन[11] तब से उनका उपयोग बड़ी संख्या में डोमेन में किया गया है, विशेष रूप से नए नियंत्रण प्रवाह को परिभाषित करने के लिए है।[12]

जटिल उदाहरण :

 (reset
   (begin
     (shift k (cons 1 (k (void)))) ;; (1)
     null))

shift द्वारा कैप्चर किया गया संदर्भ(begin [*] null) है, जहां [*] वह है kका पैरामीटर इंजेक्ट किया जाता है। shift के अंदर k इस संदर्भ का मूल्यांकन करता है (void) = #<void> को प्रतिस्थापित करने के साथ मूल्यांकन करती है, इसलिए(k (void)) का मान(begin #<void> null) = null है। shift का मुख्य भाग, अर्थात् (cons 1 null) = (1), अंतिम परिणाम के रूप में reset अभिव्यक्ति का समग्र मूल्य बन जाता है।

जो इस उदाहरण को और अधिक जटिल बनाते है:

 (reset
   (begin
     (shift k (cons 1 (k (void))))
     (shift k (cons 2 (k (void))))
     null))

यदि हम सबसे पहले टिप्पणी करें करते हैं, तो हम पहले से ही परिणाम जानते हैं, यह है (2); इसलिए हम इस प्रकार अभिव्यक्ति को फिर से लिख सकते हैं:

 (reset
   (begin
     (shift k (cons 1 (k (void))))
     (list 2)))

यह उचित है, और इसे इस रूप में फिर से लिखा जा सकता है (cons 1 (list 2)),(list 1 2).

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

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

और सूचियों के निर्माण में इसका उपयोग करें:

 (reset (begin
          (yield 1)
          (yield 2)
          (yield 3)
          null))    ;; (list 1 2 3)

यदि हम cons को stream-cons से प्रतिस्थापित करते हैं, तो हम मंद स्ट्रीम बना सकते हैं:

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

  (define lazy-example
    (reset (begin
            (stream-yield 1)
            (stream-yield 2)
            (stream-yield 3)
            stream-null)))

हम इसे सामान्यीकृत कर सकते हैं और सूचियों को स्ट्रीम में परिवर्तित कर सकते हैं:

 (define (list->stream xs)
   (reset (begin
            (for-each stream-yield xs)
            stream-null)))

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

 (define (for-each->stream-maker for-each) 
   (lambda (collection) 
     (reset (begin 
              (for-each (lambda (element) 
                          (shift k 
                            (stream-cons element (k 'ignored)))) 
                        collection) 
              stream-null))))

reset और shift के बीच के हिस्से में lambda और for-each के लिए नियंत्रण कार्य सम्मलित हैं; लैम्ब्डा का उपयोग करके इसे दोबारा लिखना असंभव है[why?].

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

संदर्भ

  1. 1.0 1.1 Felleisen, Matthias (1988). "प्रथम श्रेणी के संकेतों का सिद्धांत और व्यवहार". Principles of Programming Languages. pp. 180–190. doi:10.1145/73560.73576. ISBN 0-89791-252-7. S2CID 16705769.
  2. 2.0 2.1 2.2 Felleisen, Matthias; Friedman, Daniel P.; Duba, Bruce; Marrill, John (February 1987). निरंतरता से परे (PDF) (Technical report). Computer Science Department, Indiana University. 216.
  3. Felleisen, Matthias (1987). The Calculi of Lambda-v-CS Conversion: A Syntactic Theory of Control and State in Imperative Higher-Order Programming Languages (PDF) (Thesis).
  4. Sitaram, Dorai; Felleisen, Matthias (1990). "सीमांकक और उनके पदानुक्रम को नियंत्रित करें" (PDF). Lisp and Symbolic Computation. 3: 67–99. doi:10.1007/BF01806126. S2CID 31430221.
  5. 5.0 5.1 Danvy, Olivier; Filinski, Andrzej (1990). "सार नियंत्रण". LISP and Functional Programming. pp. 151–160. doi:10.1145/91556.91622. ISBN 0-89791-368-X. S2CID 6426191.
  6. Danvy, Olivier (2006). डेटा ऑब्जेक्ट के रूप में प्रोग्राम के लिए एक विश्लेषणात्मक दृष्टिकोण (Thesis). doi:10.7146/aul.214.152.
  7. Rémy, Didier; Gunter, Carl; Riecke, Jon G. (1995). "एमएल जैसी भाषाओं में अपवादों और नियंत्रण का सामान्यीकरण". Functional Programming Language and Computer Architecture.
  8. उदाहरण के लिए, द्वारा प्रस्तावित ऑपरेटरों को देखें racket/control रैकेट (प्रोग्रामिंग भाषा) लाइब्रेरी [1]; निम्नलिखित उदाहरणों का उपयोग करके रैकेट में चलाया जा सकता है (require racket/control)
  9. Biernacki, Dariusz; Danvy, Olivier; Shan, Chung-chieh (2006). "On the Static and Dynamic Extents of Delimited Continuations". Science of Computer Programming. 60 (3): 274–297.
  10. Gasbichler, Martin; Sperber, Michael (2002). International Conference on Functional Programming. CiteSeerX 10.1.1.11.3425.
  11. Johnson, Gregory F. (June 1987). "GL: a denotational testbed with continuations and partial continuations". Proc. SIGPLAN '87 Symposium on Interpreters and Interpretive Techniques. pp. 218–225.
  12. Queinnec, Christian (April 1994). "उच्च स्तरीय नियंत्रण ऑपरेटरों की एक लाइब्रेरी". Lisp Pointers, ACM SIGPLAN Special Interest Publ. On Lisp. École Polytechnique and INRIA-Rocquencourt. 6: 11–26. CiteSeerX 10.1.1.29.4790.


बाहरी संबंध