मुझे यह खंड पहले पढ़ने पर उलझन में पाया गया, और केवल इसे जारी रखना शुरू हुआ जब मैं निरंतरता और निरंतरता-गुजरने वाली शैली (जो यह है) के बारे में कहीं और पढ़ता था।
जो कुछ आप पहले से प्राप्त कर रहे हैं उसे समझाने के जोखिम पर, मुझे यह देखने का एक तरीका है कि "कलेक्टर" या "निरंतरता" के बारे में सोचने के लिए फंक्शन के मूल्यों को वापस करने के लिए सामान्य तरीके को बदलना है। प्रोग्रामिंग की सामान्य शैली में, आप एक फ़ंक्शन कॉल करते हैं, एक मान प्राप्त करते हैं, और कॉलर में इसके साथ कुछ करते हैं। उदाहरण के लिए, मानक रिकर्सिव length
फ़ंक्शन में गैर-खाली मामले के लिए (+ 1 (length (cdr list)))
अभिव्यक्ति शामिल है। इसका मतलब है कि एक बार (length (cdr list))
एक मान देता है, जो गणना करता है उसके साथ होने वाली गणना की गणना होती है, जिसे हम (+ 1 [returned value])
के रूप में सोच सकते हैं। सामान्य प्रोग्रामिंग में, दुभाषिया इन लंबित गणनाओं का ट्रैक रखता है, जो "ढेर" होते हैं, जैसा कि आप पुस्तक के पहले अध्यायों में देख सकते हैं। उदाहरण के लिए, एक सूची की लंबाई की गणना करने के क्रम में हमारे पास "प्रतीक्षा कंप्यूटेशंस" का घोंसला है क्योंकि सूची लंबे समय तक गहराई से कई स्तर है।
निरंतरता-गुजर शैली में, बजाय एक समारोह बुला और का उपयोग कर लौटे बुला समारोह में परिणाम की, हम समारोह जब यह कॉल करने के लिए एक "निरंतरता" के साथ उपलब्ध कराने के द्वारा अपने मूल्य पैदा करता है कि क्या करना है बताओ। (यह एसिंक्रोनस जावास्क्रिप्ट प्रोग्रामिंग में कॉलबैक के साथ आपको क्या करना है, उदाहरण के लिए: result = someFunction();
लिखने के बजाय आप someFunction(function (result) { ... })
लिखते हैं, और result
का उपयोग करने वाले सभी कोड कॉलबैक फ़ंक्शन के अंदर जाते हैं)।
यहां length
निरंतरता-गुजरने वाली शैली में है, बस तुलना के लिए। मैंने निरंतरता पैरामीटर return
कहा है, जो सुझाव देना चाहिए कि यह यहां कैसे कार्य करता है, लेकिन याद रखें कि यह किसी अन्य की तरह सामान्य योजना चर है। (अक्सर इस शैली में निरंतरता पैरामीटर k
कहा जाता है)।
(define (length/k lis return)
(cond ((null? lis) (return 0))
(else
(length/k (cdr lis)
(lambda (cdr-len)
(return (+ cdr-len 1)))))))
an article on continuations by Little Schemer co-author Dan Friedman में इस तरह के कोड को पढ़ने के लिए एक सहायक युक्ति है। (पेज 8 पर शुरू होने वाली धारा II-5 देखें)।टीका, यहाँ क्या else
खंड ऊपर का कहना है:
कल्पना करें कि आप (cdr lis)
पर length/k
बुला का परिणाम है, और फोन यह cdr-len
, तो एक जोड़ सकते हैं और यह इसके अलावा अपने निरंतरता का परिणाम पारित (return
) ।
ध्यान दें कि यह लगभग ठीक दुभाषिया समारोह के सामान्य संस्करण में (+ 1 (length (cdr lis)))
का मूल्यांकन (सिवाय इसके कि यह मध्यवर्ती परिणाम (length (cdr lis))
करने के लिए एक नाम देने के लिए नहीं है में क्या करना है क्या है। चारों ओर उत्तीर्ण होकर निरंतरता या कॉलबैक हमने कंट्रोलर को ट्रैक रखने के बजाय नियंत्रण प्रवाह (और मध्यवर्ती मूल्यों के नाम) को स्पष्ट कर दिया है।
चलिए evens-only*&co
में प्रत्येक खंड में इस विधि को लागू करते हैं। यह यहां थोड़ा जटिल है तथ्य यह है कि यह फ़ंक्शन तीन मानों के बजाय मूल्य बनाता है: विषम संख्याओं के साथ नेस्टेड सूची हटा दिया; यहां तक कि संख्याओं का उत्पाद; और विषम संख्याओं का योग। यहाँ पहले खंड है, जहां (car l)
सम संख्या होने के लिए जाना जाता है:
(evens-only*&co (cdr l)
(lambda (newl product sum)
(col (cons (car l) newl)
(opx (car l) product)
sum)))
कल्पना कीजिए कि आप विषम संख्या को हटाने के परिणाम, गुणा evens है, और सूची के cdr
से विषम संख्या जोड़ने, और उन्हें newl
, product
, और sum
क्रमशः कॉल करें। cons
सूची के प्रमुख newl
पर (क्योंकि यह एक भी संख्या है, इसे परिणाम में जाना चाहिए); सूची के प्रमुख द्वारा product
गुणा करें ( के बाद से हम शाम के उत्पाद की गणना कर रहे हैं); अकेले sum
छोड़ें; और इन को अपने प्रतीक्षा निरंतरता col
पर तीन मान पास करें।
यहाँ इस मामले में जहां सूची के सिर एक विषम संख्या है: जैसा कि पहले
(evens-only*&co (cdr l)
(lambda (newl product sum)
(col newl product (op+ (car l) sum))))
, लेकिन निरंतरता के लिए (यानी "वापसी" उन्हें) newl
और product
का एक ही मान पास, sum
और सूची के प्रमुख के साथ, क्योंकि हम विषम संख्याओं को जोड़ रहे हैं।
और यहाँ पिछले एक है, जहां (car l)
एक नेस्टेड सूची है, और जो थोड़ा डबल प्रत्यावर्तन द्वारा जटिल है:
(evens-only*&co (car l)
(lambda (newl product sum)
(evens-only*&co (cdr l)
(lambda (dnewl dproduct dsum)
(col (cons newl dnewl)
(opx product dproduct)
(op+ sum dsum))))))
कल्पना कीजिए कि आप, को हटाने संक्षेप और जोड़ने नंबरों से परिणाम हो (car l)
में और इन newl
, product
, और sum
पर कॉल करें; तो कल्पना करें कि आपके पास (cdr l)
, पर एक ही चीज़ करने से परिणाम हैं और उन्हें dnewl
, dproduct
और dsum
पर कॉल करें।आपके प्रतीक्षा निरंतरता के लिए, cons
आईएनजी newl
और dnewl
(क्योंकि हम सूचियों की सूची तैयार कर रहे हैं) द्वारा उत्पादित मान दें; product
और dproduct
एक साथ गुणा करना; और sum
और dsum
जोड़ना।
सूचना: - col
, दूसरे शब्दों में हर बार जब हम एक पुनरावर्ती कॉल करते हैं, हम पुनरावर्ती कॉल, जो तर्क, l
की वर्तमान मूल्यों "पर बंद" के लिए एक नया निरंतरता है, और बदले निरंतरता का निर्माण , आप निरंतरता की श्रृंखला के बारे में सोच सकते हैं जिसे हम रिकर्सन के दौरान और अधिक पारंपरिक रूप से लिखित कार्य के "कॉल स्टैक" मॉडलिंग के रूप में बनाते हैं!
आशा है कि आपके प्रश्न का उत्तर दें। अगर मैं थोड़ा ओवरबोर्ड चला गया हूं, तो केवल इसलिए कि मैंने सोचा था कि, खुद को रिकर्सन के बाद, निरंतरता दूसरे वास्तव में साफ, दिमाग-विस्तार विचार में लिटिल शेमर और सामान्य रूप से प्रोग्रामिंग है।
स्टेपर सेट अप करने के लिए, http://stackoverflow.com/questions/10499514/y-combinator-discussion-in-the-little-schemer/10500358#10500358 – soegaard