2010-11-26 13 views
57

मुझे क्लोजर में rest और next के बीच अंतर को समझने में कठिनाई हो रही है। The official site's page on laziness इंगित करता है कि प्राथमिकता शायद rest का उपयोग करना चाहिए, लेकिन यह वास्तव में दोनों के बीच अंतर स्पष्ट रूप से स्पष्ट नहीं करता है। क्या कोई कुछ अंतर्दृष्टि प्रदान कर सकता है? क्योंकि यह पता करने के लिए nil या एक seq वापस जाने के लिए है कि क्या आलसी विपक्ष की संरचना का मूल्यांकन करने की जरूरत हैक्लोजर: बाकी बनाम

+3

यह बिंदु एक अलग उत्तर के लायक नहीं है: अब तक के उत्तरों ने पूरी तरह से स्पष्ट नहीं किया है कि '()' सच है, जबकि 'शून्य' गलत है। तो '(चलना जारी रखें [मेरा-कॉल] (अगर (मेरा-कॉल आराम करें) (चल रहा है (मेरा-कॉल आराम करो)) "समाप्त हो गया।") 'हमेशा के लिए जा रहेगा - या बल्कि, ढेर बह जाएगा - जबकि' (चलना जारी रखें [मेरा-कॉल] (अगर (अगला मेरा-कॉल) (चल रहा है (अगला मेरा-कॉल))" समाप्त हो गया। ") 'खत्म हो जाएगा। (ओपी ने निश्चित रूप से इसे अभी समझ लिया है; मैं दूसरों के लिए यह टिप्पणी जोड़ रहा हूं।) – Mars

उत्तर

55

पेज आप वर्णित संबंद्ध हैं, next (के नए व्यवहार) rest तुलना में अधिक कड़ाई है।

rest दूसरी ओर हमेशा एक सीईसी देता है, इसलिए जब तक आप वास्तव में rest के परिणाम का उपयोग नहीं करते हैं तब तक कुछ भी मूल्यांकन करने की आवश्यकता नहीं होती है। दूसरे शब्दों में, restnext से अधिक आलसी है।

(next '(1)) 
=> nil 

तो next अगली बात को देखता है और यदि पंक्ति रिक्त है यह एक खाली seq के बजाय nil रिटर्न:

+0

ठीक है, मुझे लगता है कि मैं समझ सकता हूं कि आपका क्या मतलब है। क्या आप कह रहे हैं कि' अगला 'हमेशा एक रिटर्न देता है विपक्षी कोशिका, जबकि 'बाकी' केवल एक आईएसईक (या वास्तव में जो कुछ भी है) लौटाता है? –

+1

@ डैनियल: 'अगली' रिटर्न 'शून्य 'या एक खाली खाली' सीईसी '।' बाकी 'हमेशा' seq' देता है, जो खाली हो सकता है। – sepp2k

+0

तो मैं इसे लेता हूं, कुछ अनुक्रमों के लिए, यह निर्धारित करना कि क्या अधिक तत्व हैं एक महंगा ऑपरेशन है। विपक्षी कोशिकाओं की सामान्य सूची के साथ, मुझे लगता है कि यह निर्धारित करने के लिए तुच्छ है कि आप अंत तक पहुंच गए हैं या नहीं सूची। हालांकि, आलसी अनुक्रम (आलसी-सेक से, शायद) के साथ, यह दृढ़ संकल्प महंगा हो सकता है। I काफी समझ में नहीं आया कि खाली खाली खाली से अलग था। ऐसा लगता है कि बाद में उत्पादन कमजोर गारंटी देता है और इसलिए, अधिक कुशल हो सकता है। –

27

यह आप इस अगर आसान है। इसका मतलब यह है कि इसे आगे देखने की आवश्यकता है (पहले आइटम पर यह वापस आ जाएगा) जो इसे पूरी तरह से आलसी नहीं बनाता है (शायद आपको अगले मूल्य की आवश्यकता नहीं है, लेकिन next आगे देखने के लिए गणना समय बर्बाद कर देता है)।

(rest '(1)) 
=>() 

rest आगे नहीं लगती है और सिर्फ seq के बाकी देता है।

शायद आपको लगता है कि यहां दो अलग-अलग चीजों का उपयोग क्यों परेशान करते हैं? कारण यह है कि आप आमतौर पर जानना चाहते हैं कि सीईसी में कुछ भी नहीं बचा है और केवल nil लौटाएं, लेकिन कुछ मामलों में जहां प्रदर्शन बहुत महत्वपूर्ण है और एक और आइटम का मूल्यांकन करने का जबरदस्त प्रयास हो सकता है, आप rest का उपयोग कर सकते हैं।

+7

सिर्फ इसे मारने के लिए: (बाकी शून्य) =>() – gtrak

19

next(seq (rest ...)) जैसा है।

rest अनुक्रम के शेष भाग को वापस कर देगा। अगर अनुक्रम का वह टुकड़ा अभी तक महसूस नहीं हुआ है, rest इसे मजबूर नहीं करता है। अनुक्रम में अधिक तत्व शेष होने पर यह आपको यह भी नहीं बताएगा।

next वही काम करता है लेकिन फिर अनुक्रम के कम से कम एक तत्व को महसूस किया जाता है। तो यदि nextnil देता है, तो आप जानते हैं कि अनुक्रम में कोई और तत्व शेष नहीं है।

2

मैं अब, reursion साथ next का उपयोग करना पसंद के रूप में बच मूल्यांकन सरल/क्लीनर है: rest प्रयोग करने के लिए

(loop [lst a-list] 
    (when lst 
     (recur (next lst)) 

बनाम

(loop [lst a-list] 
    (when-not (empty? lst) ;; or (when (seq? lst) 
     (recur (rest lst)) 

एक मामला है, हालांकि, हो सकता है अगर आप कतार या ढेर के रूप में संग्रह का उपयोग करें। उस स्थिति में आप अंतिम कार्य को पॉप या डिक्यू करते समय अपने फ़ंक्शन को खाली संग्रह वापस करना चाहते हैं।

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