2011-11-19 11 views
13

एक let रूप में (Clojure यहाँ) मैं की तरहडीफ़ फॉर्म में कोई विनाश क्यों नहीं?

(let [[u s v] (svd A)] 
    (do-something-with u v)) 

जहां svd लंबाई तीन की सूची लौटाता है कुछ कर सकते हैं। यह करने के लिए बात की एक बहुत ही स्वाभाविक तरह है, तो क्यों है कि हम हम

(def [u s v] (svd A)) 

और def प्रपत्र के डिफ़ॉल्ट व्यवहार के रूप में अपनी विभिन्न सामान्यीकरण की जरूरत नहीं है नहीं है? मैं नहीं देखता कि यह किसी भी चीज़ से हस्तक्षेप कैसे करेगा def पहले से ही कर रहा है। क्या कोई जो लिस्प या क्लोजर के ज़ेन को समझता है, वह बता सकता है कि deflet के रूप में शक्तिशाली के रूप में बाध्यकारी (विनाशकारी के साथ) का समर्थन क्यों नहीं करता है?

उत्तर

15

def कंपाइलर स्तर पर एक विशेष रूप है: यह एक वर बनाता है। def को उपलब्ध होना चाहिए और विनाशकारी उपलब्ध होने से पहले प्रयोग योग्य होना चाहिए। आप let* साथ कुछ इसी तरह देखते हैं, एक संकलक आदिम कोई destructuring का समर्थन करता है कि: तो clojure/core.clj में कई हजार लाइनों के बाद भाषा अंत में पर्याप्त शक्तिशाली destructuring साथ let का एक संस्करण प्रदान करने के लिए, let* के शीर्ष पर एक मैक्रो के रूप में है।

यदि आप चाहते हैं, तो आप एक मैक्रो (कहें, def+) लिख सकते हैं जो आपके लिए यह करता है। व्यक्तिगत रूप से मुझे लगता है कि यह थोडा सकल है और इसका उपयोग नहीं करेगा, लेकिन लिस्प का उपयोग करने का अर्थ है ऐसी भाषा का उपयोग करना जो आपको व्यक्तिगत रूप से उपयुक्त बनाता है।

+1

मुझे लगता है कि यह उस तरह का उत्तर है जिसमें मुझे रूचि थी। मेरे हिस्से पर अत्यधिक संपादकीयकरण के जोखिम पर, मुझे लगता है कि आप कह रहे हैं कि क्लोजर में ऐसा नहीं किया गया है आंशिक रूप से तकनीकी है (उसमें 'def' होता है कंपाइलर आदिम), और आंशिक रूप से सम्मेलन द्वारा (उसमें (जैसे रिच हिकी) एक आदिम 'डीफ' * के साथ शुरू हो सकता था और बाद में कोर में किसी बिंदु पर' def' घोषित किया गया था)। –

+1

@ गैब्रियल मिशेल हाँ, यह संभव होगा। लेकिन यह 'let' के लिए 'def' के लिए बहुत कम उपयोगी है, और समरूपता की कमी होगी। 'चलो '** हमेशा ** उस के अंदर एक वेक्टर और विनाश लेता है; 'def' करने के लिए ऐसा करना बहुत कम सुविधाजनक होगा, और डीफ को या तो प्रतीक या विनाशकारी रूप को स्वीकार करने के लिए बहुत भयानक आईएमओ है। – amalloy

+0

क्या आप इस बारे में कुछ और कह सकते हैं कि ऐसा मैक्रो सकल क्यों होगा? अभी, मैं सोच रहा हूं कि यह एक अच्छा विचार है- लेकिन, आपकी टिप्पणी के आधार पर, मैं यह भी सोच रहा हूं कि यह किसी भी तरह क्लोजर के अनाज के खिलाफ चलाएगा। आम तौर पर भाषा के अनाज के साथ जाना बेहतर होता है जो इसके खिलाफ चलता है जो कुछ भी करता है लेकिन भाषा के साथ अनुभवहीन किसी के लिए अपील करता है। तथ्य यह है कि 10 वर्षों के बाद, इस तरह के मैक्रो का उपयोग आम नहीं है और आगे मुझे आश्चर्य होता है कि अगर यह किसी अन्य तरीके से हल की गई समस्या का एक कठोर समाधान है। –

2

def मूल रूप से वर्स के लिए निर्माता है। पहला तर्क प्रतीक है जो Var नाम देता है। यह प्रतीक लेता है और उस प्रतीक के लिए एक वर देता है। विनाशकारी इन अर्थशास्त्र को बदल देगा।

आप ऐसा मैक्रो लिख सकते हैं जो यद्यपि करता है।

+1

क्या आपने 'let' के लिए समान रूप से सच नहीं कहा है? मेरा मतलब यह नहीं कह सकता कि 'चलो' को विनाशकारी बांध का समर्थन नहीं करना चाहिए? – sepp2k

+1

हां, sepp2k उस बिंदु को सामने लाता है जिसके बारे में मैं सोच रहा हूं। जहां तक ​​मैं समझता हूं, 'डीफ़' और 'लेट' के बीच मूल अंतर बाइंडिंग का दायरा है, और फिर भी 'चलो' का सामान्य व्यवहार होता है। चूंकि चक बताते हैं, तथ्य यह है कि आप एक मैक्रो लिख सकते हैं जो पहले तर्क में बहुलक है (एक प्रतीक के लिए एक व्यवहार, प्रतीकों की सूचियों के लिए एक और व्यवहार) मुझे आश्चर्य करता है कि यह डिफ़ॉल्ट कार्यान्वयन क्यों नहीं है। –

0

यह सही नहीं है लेकिन यह एक def+ https://clojuredocs.org/clojure.core/destructure

(defmacro def+ 
    "binding => binding-form 
    internalizes binding-forms as if by def." 
    {:added "1.9", :special-form true, :forms '[(def+ [bindings*])]} 
    [& bindings] 
    (let [bings (partition 2 (destructure bindings))] 
    (sequence cat 
     ['(do) 
     (map (fn [[var value]] `(def ~var ~value)) bings) 
     [(mapv (fn [[var _]] (str var)) bings)]]))) 
जो आप कर सकते के साथ

लिखने पर शुरू होता है ...

(def+ [u s v] [1 5 9], foo "bar") 

... जबकि def की सादगी समझौता नहीं ...

(def+ foo "bar") 

.. जो अनुरोध किया गया था और सुझाव दिया गया था। यह अभी भी वैश्विक नामस्थान में gensym चर प्रस्तुत करने का मुद्दा है। जीन्सिम समस्या को संभाला जा सकता है लेकिन उपयोग केस (प्रतिलिपि में उपयोग) अतिरिक्त चर शायद स्वीकार्य हैं।

1

कुछ दार्शनिक औचित्य क्या हैं।

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

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

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