2012-02-07 10 views
5

क्लोजर में आप कोड उत्पन्न करने के लिए मूल्यों की एक सूची को अलग-अलग कर सकते हैं, उदा।आप सामान्य (अनिश्चित) कोड में क्यों विभाजित नहीं हो सकते हैं?

(def extra-values [1 2 3 4]) 

`(+ 100 200 [email protected]) 
=> (clojure.core/+ 100 200 1 2 3 4) 

यह तार्किक लगता है कि एक ही दृष्टिकोण को एक अज्ञात संदर्भ में काम करना चाहिए, उदा।

(def extra-values [1 2 3 4]) 

(+ 1000 [email protected]) 
=> [an error, but one could argue that the answer should be 1010??] 

क्या कोई गहरा तकनीकी/दार्शनिक कारण है कि यह काम नहीं कर सकता है?

+0

शायद भाषा के लिए "सामान्य" सुविधा के साथ भाषा के "मेटा" सुविधा के मिश्रण से बचने के लिए :) – Ankur

उत्तर

13

एक साधारण कारण यह है कि तब

`(+ 100 200 [email protected]) 

खराब परिभाषित किया जाएगा है: यह

(+ 100 200 [email protected]) 

को

(+ 100 200 1 2 3 4) 

या का विस्तार करता है? दोनों संदर्भ मान्य हैं यदि [email protected] निर्माण उस संदर्भ में कानूनी है।

यह मैक्रो सिस्टम में गंभीर समस्याएं भी पैदा करता है।

(defmacro foo [x & args] 
    `(list ~x ~(count args))) 

(let [data '(1 2 3)] 
    (foo "three" [email protected])) 

foo कैसे पता चल सकता है कि यह किस प्रकार से गुजर रहा है? यह निश्चित रूप से संकलन-समय पर विस्तार नहीं कर सकता है, इसलिए अब अनक्वोट-स्प्लिसिंग केवल में कुछ गैर-उद्धृत संदर्भों में मान्य है।

और समग्र यह सिर्फ कोर अवधारणाओं के गरीब समझ के लिए समायोजित करने के लिए भाषा को muddying है - यदि आप वास्तव में गंदें शब्द बोलना-जोड़ के लिए एक जटिल तर्क सूची का निर्माण करना चाहते, तो आप आसानी apply कुछ में

(apply + `(100 [email protected] 200)) 
+0

अच्छा जवाब है, मुझे पसंद है: हम पहले से ही है कि (कुछ और सीमाओं के साथ) apply में कार्यक्षमता है उदाहरण। धन्यवाद! – mikera

2
की तरह उपयोग कर सकते हैं

syntax-quote, unquote, और unquote-splicing का बिंदु डेवलपर को मैक्रोज़ लिखने में मदद करना है। - नहीं repl

user=> `(:a ~extra-values) 
(:a [1 2 3 4]) 

पूर्व के मामले में यह पाठक के लिए कठिन (मानव पाठक है में:

उदाहरण के लिए, syntax-quote और unquote बिना आप

user=> (list :a extra-values) 
(:a [1 2 3 4]) 
बजाय

लिखने के लिए होता है) यह समझने के लिए कि परिणामस्वरूप फॉर्म कैसा दिख रहा है, जबकि बाद वाला मामला परिणामी रूप के 'आकार' को बनाए रखता है।

तो vector[1 2 3 4] के बजाय यदि हम extra-values की सामग्री को परिणामी रूप में विभाजित करना चाहते हैं तो क्या होगा?हम unquote-splicing की जरूरत है ताकि हम लिख सकते हैं:

user=> `(+ 100 200 [email protected]) 
(clojure.core/+ 100 200 1 2 3 4) 

के बजाय:

user=> (concat `(+ 100 200) extra-values) 
(clojure.core/+ 100 200 1 2 3 4) 

फिर unquote-splicing संस्करण जिसके परिणामस्वरूप फ़ॉर्म के 'आकार' जब कोड मूल्यांकन किया जाता है के समान कोड की अनुमति देता है, जबकि बाद के संस्करण में 'आकार' apply और list के शोर में खो जाता है।

ये दोनों उदाहरण बहुत ही सरल हैं, लेकिन syntax-quote और अधिक जटिल मैक्रोज़ लिखते समय दोस्त वास्तव में अपने आप आते हैं।

आप अपने प्रश्न पर वापस आ रहे हैं कि आप (+ 1000 [email protected]) क्यों नहीं लिख सकते हैं?

user=> (apply + 1000 extra-values) 
1010 
संबंधित मुद्दे