2016-03-08 8 views
6

Clojure में साथ, एक समारोह for या दुष्प्रभाव के लिए doseq साथ इसी तरह और वापसी मान के रूप में नहीं के बराबर हो रही है की मदद से एक दृश्य से अधिक पुनरावृति कर सकते हैं के लिए:का उपयोग doseq/अनंत दृश्यों

(doseq [x (range 3)] 
    (prn x)) 

; 0 
; 1 
; 2 
के लिए

केस अनुक्रम अनंत है, ब्रेक हालत पेश करने का एक तरीका है:

(doseq [x (range) :while (< x 3)] 
    (prn x)) 

यह उपरोक्त के समान उत्पादन का उत्पादन करेगा।

एक विशेष रूप से एक से अधिक अनुक्रम का उपयोग करते समय एक बहुत ही रोचक व्यवहार होता है। जैसा कि प्रलेखन इसे कॉल करता है: "संग्रह घोंसला वाले फैशन में पुनरावृत्त होते हैं, सबसे तेज़"।

(doseq [x (range 3) y (range 3)] 
    (prn x y)) 

; 0 0 
; 0 1 
; 0 2 
; 1 0 
; 1 1 
; 1 2 
; 2 0 
; 2 1 
; 2 2 

हालांकि, यदि दृश्य फिर से अनंत हैं तो क्या होता है। जब अंतिम व्यक्ति अनंत होता है, तो यह काफी अच्छा काम करता है। इस से पहले उदाहरण के रूप में समान रूप से काम करेगा:

(doseq [x (range 3) y (range) :while (< y 3)] 
    (prn x y)) 

पहले एक अनंत है, तो परिणामी उत्पादन की उम्मीद है के रूप में, लेकिन कुछ कारणों के लिए पाश के बाद अंतिम पंक्ति छपा है नहीं रूकती है। दूसरे शब्दों में: प्रतिलिपि काम करता रहता है।

(doseq [x (range) y (range 3) :while (< x 3)] 
    (prn x y)) 

क्या कोई इस व्यवहार को समझा सकता है?

+0

'(स्रोत doseq)' - और वैकल्पिक रूप से '(macroexpand ')' पर एक नज़र डाला था? – birdspider

+0

ओह, बस एक नज़र था। अब तक मेरे ज्ञान के लिए थोड़ा गहरा ... –

उत्तर

13

यह नहीं है भावना:

(doseq [x (range) 
     y (range 3) 
     :while (< x 3)] 
    (prn x y)) 

यह होना चाहिए:

(doseq [x (range) 
     :while (< x 3) 
     y (range 3)] 
    (prn x y)) 

... जो समाप्त हो जाता है।

इसके बारे में लगता है कि इस तरह से:

(doseq [x (range)] 
    (doseq [y (range 3) 
      :while (< x 3)] 
    (prn x y))) 

बनाम:

(doseq [x (range) 
     :while (< x 3)] 
    (doseq [y (range 3)] 
    (prn x y))) 

मूल संस्करण में, बाहरी पाश अनंत होती है, फिर उस आंतरिक छोरों में :while एक फर्क नहीं है। लूप जारी है, यह कुछ भी नहीं करता है। निश्चित संस्करण :while बाहरी लूप को समाप्त करता है।

+0

अच्छा लग रहा है और पूरी तरह से काम करता है! स्पष्टीकरण के लिए धन्यवाद .. –

+1

वाह, मुझे कभी नहीं पता था कि स्थिति का आदेश/प्लेसमेंट महत्वपूर्ण था। –

0

मुहुक के उत्कृष्ट स्पष्टीकरण को देखते हुए, यह स्पष्ट होने और कोड को अधिक संपीड़ित करने के लिए एक अच्छा तर्क की तरह प्रतीत होता है। तो शायद इस तरह:

(doseq [x (range 3)] 
    (doseq [y (range 3)] 
    (prn x y))) 

अगर आप इनपुट अनुक्रम, या इस तरह नियंत्रित कर सकते हैं:

(let [x-vals (range) 
     y-vals (range) ] 
    (doseq [x x-vals :while (< x 3)] 
    (doseq [y y-vals :while (< y 3)] 
     (prn x y)))) 

इनपुट अनुक्रम (x-vals जैसे या y-vals) फोन करने वाले से आप के लिए प्रदान की जाती है, तो।

संबंधित मुद्दे