2012-03-09 11 views
9

मैं Clojure 1.2.1 में इस व्यवहार को देखें:(नहीं = (प्रकार `(1)) (प्रकार` (1 2))) ;; क्यूं कर? (एक तत्व सूची, वाक्य रचना-बोली, विपक्ष, PersistentList)

user=> (type '(1 2)) 
clojure.lang.PersistentList 
user=> (type `(1 2)) ;; notice syntax-quote 
clojure.lang.Cons 
user=> (type '(1)) 
clojure.lang.PersistentList 
user=> (type `(1)) 
clojure.lang.PersistentList 

मैं उम्मीद `(1) एक विपक्ष होने के लिए जैसे` (1 2) है ।

मैं भी करने की कोशिश की:

user=> (type (cons 1 nil)) 
clojure.lang.PersistentList 
user=> (type (cons 1 `())) 
clojure.lang.Cons 
user=> (type (cons 1 '())) 
clojure.lang.Cons 
user=> (type (cons 1 [])) 
clojure.lang.Cons 

तो के लिए `PersistentLists (1) और (विपक्ष 1 शून्य) होने के लिए क्या कारण है?

उत्तर

4

अमालोय कहते हैं, आपको उन सटीक प्रकारों के खिलाफ प्रोग्राम नहीं करना चाहिए, लेकिन seq अमूर्तता के खिलाफ प्रोग्राम नहीं करना चाहिए।

हालांकि, मुझे लगता है कि मैं इस कारण अनुमान लगा सकता हूं। क्लोजर फॉर्म जो PersistentList उत्पन्न करते हैं अंततः RT.java पर कॉल करते हैं, विशेष रूप से cons(Object x, Object coll) विधि। यह एक बहुत ही अजीब जांच के साथ शुरू होता है: if(coll == null) return new PersistentList(x), जिसके बाद यह Cons ऑब्जेक्ट बनाता है यदि वह चेक पास नहीं होता है। आप earlier versions of the code को देखो, तो आप इस पा सकते हैं: समारोह के पिछले संस्करण में

static public IPersistentCollection cons(Object x, IPersistentCollection y) { 
    if(y == null) 
     return new PersistentList(x); 
    return y.cons(x); 
} 

तो, कॉल दूसरा तर्क की cons विधि के लिए भेजा गया है, तो मामला है जब दूसरा तर्क null था (यानी क्लोजर में nil) को विशेष हैंडलिंग की आवश्यकता है। बाद के संस्करण उस प्रेषण को नहीं करते हैं (या वास्तव में इसे अलग-अलग तरीके से करते हैं, संभावित रूप से संग्रह प्रकारों की एक बड़ी विविधता का समर्थन करने के लिए), लेकिन चेक को बरकरार रखा गया है क्योंकि यह किसी भी सही ढंग से लिखित कोड को तोड़ता नहीं है।

+0

उत्तर के लिए धन्यवाद! यह व्यवहार बताता है। मैंने सोचा कि चीजों को इस तरह से काम करने का एक अच्छा कारण है, लेकिन अगर मैं सही ढंग से समझता हूं तो यह सिर्फ एक quirk है, है ना? –

+0

मुझे ऐसा लगता है। यदि आप वास्तव में जानना चाहते हैं, तो उस चेक को हटाने का प्रयास करें और देखें कि कुछ भी टूट जाता है या नहीं। –

+0

मैं शायद करूँगा। धन्यवाद। –

4

यदि आप अंतर की परवाह करते हैं, तो आपका प्रोग्राम गलत है। वे दोनों seqs हैं, इस अर्थ में कि (seq? x) सच देता है; बाकी कार्यान्वयन विवरण हैं जिन पर आपको निर्भर नहीं होना चाहिए।

+1

मुझे किसी भी कार्यक्रम के लिए इसकी आवश्यकता नहीं है :) मुझे बस क्लोजर के बारे में कुछ सीखने की उम्मीद है। –

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