क्लोजर: कॉन (seq) बनाम कॉन्स (सूची)


98

मुझे पता है कि consएक seq conjदेता है और एक संग्रह लौटाता है। मुझे यह भी पता है कि conjआइटम संग्रह के इष्टतम अंत में cons"जोड़ता है" , और हमेशा सामने वाले आइटम को "जोड़ता है"। यह उदाहरण इन दोनों बिंदुओं को दर्शाता है:

user=> (conj [1 2 3] 4) ; returns a collection
[1 2 3 4]
user=> (cons 4 [1 2 3]) ; returns a seq
(4 1 2 3)

वैक्टर, नक्शे और सेट के लिए ये अंतर मेरे लिए मायने रखते हैं। हालाँकि, सूचियों के लिए वे समान लगते हैं।

user=> (conj (list 3 2 1) 4) ; returns a list
(4 3 2 1)
user=> (cons 4 (list 3 2 1)) ; returns a seq
(4 3 2 1)

क्या सूची के उपयोग से कोई उदाहरण हैं जहां conjबनाम consअलग-अलग व्यवहार प्रदर्शित करते हैं, या क्या वे वास्तव में विनिमेय हैं? अलग तरीके से फंसाया गया, क्या ऐसा उदाहरण है जहां एक सूची और एक seq का समान रूप से उपयोग नहीं किया जा सकता है?

जवाबों:


150

एक अंतर यह है कि conjकिसी संग्रह में सम्मिलित करने के लिए किसी भी तर्क को स्वीकार करता है, जबकि consसिर्फ एक लेता है:

(conj '(1 2 3) 4 5 6)
; => (6 5 4 1 2 3)

(cons 4 5 6 '(1 2 3))
; => IllegalArgumentException due to wrong arity

एक और अंतर रिटर्न मूल्य के वर्ग में है:

(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList

(class (cons 4 '(1 2 3))
; => clojure.lang.Cons

ध्यान दें कि ये वास्तव में विनिमेय नहीं हैं; विशेष रूप से, clojure.lang.Consको लागू नहीं करता है clojure.lang.Counted, तो एक countउस पर नहीं रह गया है एक निरंतर समय ऑपरेशन (इस मामले में यह शायद 1 + 3 को कम करेगा है - 1, पहला तत्व से अधिक रैखिक ट्रावर्सल से आता है 3 से आता (next (cons 4 '(1 2 3))जा रहा है एक PersistentListऔर इस प्रकार Counted)।

नामों के पीछे का इरादा है, मेरा मानना ​​है, consइसका मतलब है कि विपक्ष (एक seq को चखना) 1 है , जबकि conjइसका मतलब संयोजन (एक संग्रह पर एक आइटम को इंगित करना ) है। seqद्वारा निर्माण किया जा रहा consतत्व अपनी पहली तर्क के रूप में पारित कर दिया साथ शुरू होता है और उसके के रूप में है next/ restभाग बात के आवेदन से उत्पन्न seqदूसरा तर्क करने के लिए; जैसा कि ऊपर दिखाया गया है, पूरी बात कक्षा की है clojure.lang.Cons। इसके विपरीत, conjहमेशा लगभग उसी प्रकार का एक संग्रह लौटाता है, जिस तरह का संग्रह उसके पास जाता है। (मोटे तौर पर, क्योंकि इसे 9 प्रविष्टियों से आगे बढ़ते ही PersistentArrayMapबदल दिया जाएगा PersistentHashMap।)


1 परंपरागत रूप से, लिस्प दुनिया में, consविपक्ष (एक जोड़ी को चखता है), इसलिए क्लूजुर लिस्प परंपरा से प्रस्थान करता है, जिसके consकार्य में एक सीक का निर्माण होता है, जिसमें पारंपरिक नहीं होता है cdrconsमाध्य का सामान्यीकृत उपयोग "प्रोग्रामिंग प्रकारों के अध्ययन और उनके कार्यान्वयन में वर्तमान में सर्वव्यापी" कुछ प्रकार या अन्य मूल्यों को एक साथ रखने के लिए एक रिकॉर्ड का निर्माण करता है; इसका मतलब तब होता है जब "सहमति से बचने" का उल्लेख किया जाता है।


1
क्या शानदार लेखन है! मैं इस बात से अनजान था कि एक विपक्ष प्रकार था। बहुत बढ़िया!
डैनियल यांकोवस्की

धन्यवाद। सुन कर खुशी हुई। :-)
मिचेल मार्कीज

2
संयोग से, एक विशेष मामले के रूप में, (cons foo nil)एक सिंगलटन लौटाता है PersistentList(और इसी तरह conj)।
मिचेल मार्कीज

1
एक और शानदार व्याख्या। तुम सच में एक लौंग जेडी हो!
dbyrne

1
मेरे अनुभव में, सूचियों के रूप में सूचियों का इलाज करना और प्रदर्शन के मामले में seq ias महत्वपूर्ण नहीं है।
cgrand

11

मेरी समझ यह है कि आप जो कहते हैं वह सच है: एक सूची पर एक सूची पर विपक्ष के बराबर है।

आप एक "कहीं और डालें" ऑपरेशन के रूप में संयोजन के बारे में सोच सकते हैं, और "सिर पर एक सम्मिलित" ऑपरेशन होने के रूप में विपक्ष हो सकते हैं। एक सूची में, सिर पर सम्मिलित करना सबसे तर्कसंगत है, इसलिए इस मामले में संयोजन और विपक्ष बराबर हैं।


8

एक और अंतर यह है कि क्योंकि conjपहले अनुक्रम को पहले तर्क के रूप में लिया जाता है, यह कुछ क्रम में alterअद्यतन करते समय अच्छी तरह से निभाता है ref:

(dosync (alter a-sequence-ref conj an-item))

यह मूल रूप (conj a-sequence-ref an-item)से एक थ्रेड-सुरक्षित तरीके से करता है। यह साथ काम नहीं करेगा cons। अधिक जानकारी के लिए Stu Halloway द्वारा प्रोग्रामिंग लोजिक में कंजरेन्सी पर अध्याय देखें ।


2

एक और अंतर सूची के व्यवहार का है?

(list? (conj () 1)) ;=> true
(list? (cons 1 ())) ; => false

4
विपक्ष हमेशा एक क्रम देता है, जो एक ही प्रकार का प्रदान करता है
निंग सन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.