2011-01-18 7 views

उत्तर

141

अंतर यह है कि for एक आलसी अनुक्रम बनाता है और doseq जबकि साइड इफेक्ट्स निष्पादित करने के लिए है और शून्य देता है।

user=> (for [x [1 2 3]] (+ x 5)) 
(6 7 8) 
user=> (doseq [x [1 2 3]] (+ x 5)) 
nil 
user=> (doseq [x [1 2 3]] (println x)) 
1 
2 
3 
nil 

यदि आप अन्य अनुक्रमों के आधार पर एक नया अनुक्रम बनाना चाहते हैं, तो इसका उपयोग करें। यदि आप कुछ अनुक्रमों के तत्वों के आधार पर साइड इफेक्ट्स (प्रिंटिंग, डेटाबेस पर लिखना, परमाणु हथियार लॉन्च करना आदि) करना चाहते हैं, तो डोसक का उपयोग करें।

+0

शानदार उत्तर। धन्यवाद! –

+9

अब बहुत साइड इफेक्ट्स हैं ... परमाणु हथियार लॉन्च करना :) – Marc

+4

धन्यवाद! मैंने अपने (लंबे समय तक) बाल खींचकर "के लिए" खींच लिया था कि यह मेरी वस्तुओं की सूची में मेरे परमाणु हथियारों को कभी नहीं आग लगाता है। "doseq" निश्चित किया था। –

51

ध्यान दें कि doseq उत्सुक है जबकि for आलसी है। उदाहरण Rayne के जवाब में लापता

(for [x [1 2 3]] (println x)) 

आरईपीएल पर है, यह आम तौर पर आप क्या चाहते हो जाएगा, लेकिन यह मूल रूप से एक संयोग है: आरईपीएल for द्वारा उत्पादित आलसी अनुक्रम बलों, printlns होने के कारण। एक गैर-संवादात्मक वातावरण में, कभी भी मुद्रित नहीं किया जाएगा। आप क्योंकि def प्रपत्र बनाए गए नए वर, और नहीं मूल्य है जो यह स्वाभाविक है रिटर्न

user> (def lazy (for [x [1 2 3]] (println 'lazy x))) 
#'user/lazy 

user> (def eager (doseq [x [1 2 3]] (println 'eager x))) 
eager 1 
eager 2 
eager 3 
#'user/eager 

के परिणामों की तुलना द्वारा कार्रवाई में देख सकते हैं, आरईपीएल मुद्रित करने के लिए के लिए कुछ नहीं है, और lazy संदर्भित करेंगे एक अवास्तविक आलसी-सीक के लिए: इसके किसी भी तत्व की गणना नहीं की गई है। eagernil का संदर्भ लेंगे, और इसकी सभी प्रिंटिंग की जाएगी।

+0

डोसक असीमित आलसी अनुक्रम का मूल्यांकन कैसे करता है? बुरा विचार? केवल इसे सीमित अनुक्रमों पर कॉल करें, या तो उत्सुक या आलसी? – johnbakers

+0

@johnbakers यह मूल्यांकन तब तक अवरुद्ध होगा जब तक कि मूल्यांकन बाधित न हो जाए। क्लोजर सीमित अनुक्रमों की तुलना में एक अलग तरीके से असीमित अनुक्रमों को संभालने का प्रयास नहीं करता है। –

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