2013-02-21 21 views
23

में अंतर और चलो * के बीच अंतर से उलझन में कोई भी अंतर को समझा सकता है? मुझे नहीं लगता कि मैं उन पाठ्यपुस्तकों/साइटों से अवधारणा को समझता हूं जिनसे मैंने परामर्श किया है।योजना

+2

संभावित डुप्लिकेट [योजना को भ्रमित करने दें और चलो \ *] (http: // stackoverflow।कॉम/प्रश्न/8036840/योजना-भ्रमित-का-चलो और चलो) –

+4

@ डेविडफेफर - एक डुप्ली प्रतीत नहीं होता है। वह एक नेस्टेड 'चलो' और 'चलो * की एक बहुत ही विशिष्ट बातचीत के बारे में पूछ रहा है, जबकि यह एक सामान्य अवलोकन के लिए पूछ रहा है। – Inaimathi

+0

बस मशीन निष्कर्षण के मानव स्पष्टीकरण को उलझन में डाल दिया: o – Nishant

उत्तर

23

यदि आप let का उपयोग करते हैं, तो आप पहले let अभिव्यक्ति में परिभाषित बाइंडिंग का संदर्भ नहीं दे सकते। उदाहरण के लिए, इस काम करेंगे नहीं:

(let ((x 10) 
     (y (+ x 6))) ; error! unbound identifier in module in: x 
    y) 

लेकिन अगर आप let* उपयोग करते हैं, यह एक ही let* अभिव्यक्ति में पिछले बाइंडिंग का उल्लेख किया जा सकता है:

(let* ((x 10) 
     (y (+ x 6))) ; works fine 
    y) 
=> 16 

यह दस्तावेज में सभी here है।

+1

मैं इसे दस्तावेज़ीकरण में स्पष्ट रूप से नहीं देखता (जहां आपका लिंक पॉइंट, वर्तमान संस्करण 5.3.6), इसलिए मैं भी उलझन में था। 'लेट' के लिए प्रलेखन कहता है कि "पहला फॉर्म 'वैल-एक्सप्रस' बाएं से दाएं, का मूल्यांकन करता है ...", इसलिए यह स्पष्ट नहीं है कि उनका समानांतर में मूल्यांकन किया जाता है। – Alexey

+0

@Alexey यह समानांतर में उनका मूल्यांकन नहीं करता है। चूंकि दस्तावेज़ कहते हैं, * "पहला फॉर्म 'वैल-एक्सप्रस' बाएं से दाएं का मूल्यांकन करता है, प्रत्येक' आईडी' के लिए एक नया स्थान बनाता है, और मानों को स्थानों में रखता है "* - जिसका अर्थ है, पहले उनका मूल्यांकन किया जाता है और परिणामी मान एकत्र किए जाते हैं, और केवल *** *** *** प्रत्येक * 'id' * के लिए नए स्थान बनाए जाते हैं और मान प्रत्येक स्थान पर रखे जाते हैं। आप अभी भी अनुक्रमिकता देख सकते हैं यदि * 'val-exprs' * में से एक भंडारण (यानी डेटा, जैसे सूची या संरचना) को बाद में एक्सेस करता है। –

26

Let समानांतर है, (एक तरह से, नीचे देखें)let* अनुक्रमिक है। Let रूप

((lambda(a b c) ... body ...) 
    a-value 
    b-value 
    c-value) 

लेकिन let* रूप

((lambda(a) 
    ((lambda(b) 
     ((lambda(c) ... body ...) 
     c-value)) 
    b-value)) 
    a-value) 

तब्दील हो और इस तरह नेस्टेड गुंजाइश ब्लॉक पैदा कर रही है जहां b-value अभिव्यक्ति a का उल्लेख कर सकते हैं, और c-value अभिव्यक्ति b और a दोनों का उल्लेख कर सकते। a-value बाहरी दायरे से संबंधित है। यह भी

(let ((a a-value)) 
    (let ((b b-value)) 
    (let ((c c-value)) 
     ... body ...))) 

के बराबर है, यह भी letrec नहीं है पुनरावर्ती बाइंडिंग, जहां सभी चर और भाव एक साझा दायरे से संबंध रखते हैं और (प्रारंभ से संबंधित कुछ कैविएट्स के साथ) एक दूसरे के लिए उल्लेख कर सकते हैं के लिए अनुमति देता है। यह (भी, के रूप में letrec* योजना में उपलब्ध R6RS के बाद से in Racket)

(let ((a *undefined*) (b *undefined*) (c *undefined*)) 
    (set! a a-value) 
    (set! b b-value) 
    (set! c c-value) 
    ... body ...) 

के लिए या तो बराबर है, या

(let ((a *undefined*) (b *undefined*) (c *undefined*)) 
    (let ((_x_ a-value) (_y_ b-value) (_z_ c-value)) ; unique identifiers 
    (set! a _x_) 
    (set! b _y_) 
    (set! c _z_) 
    ... body ...)) 

(in Scheme) करने के लिए।

अद्यतन: let वास्तव में समानांतर में अपने मूल्य-अभिव्यक्तियों का मूल्यांकन नहीं करता है, यह सिर्फ इतना है कि उनका मूल्यांकन उसी प्रारंभिक माहौल में किया जाता है जहां let प्रपत्र प्रकट होता है। यह भी lambda आधारित अनुवाद से स्पष्ट है: पहला मान भाव प्रत्येक मूल्यांकन किया जाता है एक ही है, बाहरी वातावरण में, और जिसके परिणामस्वरूप मूल्यों एकत्र कर रहे हैं, और केवल तो नए स्थानों प्रत्येक आईडी के लिए बनाई गई हैं और मान प्रत्येक स्थान पर रखे जाते हैं। हम तब भी अनुक्रमिकता देख सकते हैं यदि मूल्य-अभिव्यक्तियों में से कोई एक स्टोरेज (यानी डेटा, एक सूची या संरचना जैसे) को बाद में एक्सेस करता है।