2010-07-11 7 views
13

(अस्वीकरण - मैं Clojure में seqs के महत्व के बारे में पता कर रहा हूँ)आम लिस्प विपक्ष दो प्रतीकों से एक सूची बनाता है, क्लोजर विपक्ष को एक सीक पर विपक्ष की आवश्यकता होती है?

आम तुतलाना में विपक्ष समारोह एक सूची में दो प्रतीकों गठबंधन करने के लिए इस्तेमाल किया जा सकता:

(def s 'x) 
(def l 'y) 
(cons s l) 

clojure में - आप कर सकते हैं केवल एक अनुक्रम पर विपक्ष - विपक्ष को दो प्रतीकों के साथ काम करने के लिए बढ़ाया नहीं गया है। तो आपको लिखना है:

(def s 'x) 
(def l 'y) 
(cons s '(l)) 

क्या क्लोजर में उच्च स्तर का पैटर्न है जो सामान्य LISP और क्लोजर के बीच इस अंतर को समझाता है?

+0

मैं क्लोजर में थोड़ा प्रोग्रामिंग कर रहा हूं और इसके बारे में भी जानकारी नहीं थी! यदि आप जो दावा करते हैं वह सही है, तो यह एक अच्छा सवाल है :) –

+0

ध्यान दें कि 'विपक्ष' से 'conj' का उपयोग करना सामान्य रूप से बेहतर होता है। अधिक जानकारी के लिए, इस प्रश्न का मेरा जवाब देखें (और cgrand द्वारा टिप्पणी): http://stackoverflow.com/questions/3008411/clojure-seq-cons-vs-list-conj (वास्तव में, वह उत्तर भी बताता है क्लोजर में 'विपक्ष' का कार्य पारंपरिक लिस्प 'विपक्ष' के विपरीत एक निश्चित डिग्री के विपरीत है।) –

+3

आपका पहला उदाहरण एक सूची नहीं है, यह एक जोड़ी है। एक जोड़ी (ए। बी) दो तत्वों (एबी) की सूची से अलग होती है, जो जोड़ी होती है (ए। (बी। एनआईएल)) – Zorf

उत्तर

9

क्लोजर में पारंपरिक लिप्स के विपरीत, सूचियां प्राथमिक डेटा संरचनाएं नहीं हैं। डेटा संरचना ISeq इंटरफ़ेस को कार्यान्वित कर सकती है - जो डेटा संरचना के बारे में एक और दृश्य है - एक ही कार्य को प्रत्येक में तत्वों तक पहुंचने की इजाजत देता है। (सूचियाँ पहले से ही इस में जब cons प्रयोग किया जाता है एक दृश्य को लागू। seq? जाँच करता है कि कुछ को लागू करता है ISeq(seq? '(1 2)), (seq? [1 2])) Clojure बस अच्छे कारण के साथ अलग तरह से काम करता है(), (यह प्रकार clojure.lang.Cons) a और (seq b) का दिया जाता है का निर्माण की वास्तव में है। (a आर्ग 1 और b आर्ग 2) जाहिर है, प्रतीकों और ISeq नहीं लागू नहीं कर सकते हैं किया जा रहा है।

Clojure.org/sequences

Sequences screencast/talk by Rich Hickey हालांकि, ध्यान दें कि rest बदल गया है, और यहमें अब पिछले व्यवहार है है 10, और lazy-cons को lazy-seq और cons द्वारा प्रतिस्थापित किया गया है। 'कार' और 'सीडीआर':

clojure.lang.RT

2

जब आप कहते हैं कि

> (cons 'a 'b) 
आम तुतलाना में

आप एक सूची है, लेकिन एक बिंदीदार जोड़ी मिल न: (a . b), जबकि

> (cons 'a (cons 'b nil)) 

का परिणाम बिंदीदार जोड़ी (a . (b . nil)) है।

पहली सूची में cdr() की सूची नहीं है, क्योंकि यह b है और nil नहीं है, जो इसे अनुचित सूची बना रही है। उचित सूचियों को nil द्वारा समाप्त किया जाना चाहिए। इसलिए mapcar() जैसे उच्च आदेश फ़ंक्शन और मित्र काम नहीं करेंगे, लेकिन हम एक विपक्ष-सेल को सहेजते हैं। मुझे लगता है कि क्लोजर के डिजाइनरों ने इस सुविधा को हटा दिया क्योंकि यह भ्रम पैदा कर सकता है।

+1

यह ध्यान दिया जाना चाहिए कि '(ए। (बी। एनआईएल)) '_is_ एक लिस्प सूची, जिसे आमतौर पर' (ab) 'के रूप में जाना जाता है। – Svante

5

कॉमन लिस्प कान्स में एक तथाकथित कान्स सेल, जो दो स्लॉट के साथ एक रिकॉर्ड के समान है बनाता है।

आप एक विपक्षी सेल के उन दो स्लॉट में कुछ भी डाल सकते हैं।

कंस कोशिकाओं का उपयोग सूचियां बनाने के लिए किया जाता है। लेकिन कोई भी विपक्षी कोशिकाओं के साथ सभी प्रकार के डेटा संरचनाएं बना सकता है: पेड़, ग्राफ, विभिन्न प्रकार की विशेष सूचियां, ...

लिस्प के कार्यान्वयन बहुत कुशल विपक्षी कोशिकाओं को प्रदान करने के लिए अत्यधिक अनुकूलित किए जाते हैं।

3

एक लिस्प सूची सूची कोशिकाओं का उपयोग करने का एक आम तरीका है (Rainer's description देखें)। क्लोजर सबसे अच्छा माना जाता है क्योंकि विपक्षी कोशिकाएं नहीं होती हैं (हालांकि कुछ ऐसा ही हो सकता है जो हुड के नीचे छिप सकता है)। क्लोजर cons एक गलत नाम है, इसे वास्तव में केवल prepend नाम दिया जाना चाहिए।

3

क्लोजर में दो-तत्व वेक्टर का उपयोग पसंद किया जाता है: [:a :b]। हुड के तहत ऐसे छोटे वैक्टर जावा सरणी के रूप में कार्यान्वित किए जाते हैं और बेहद सरल और तेज़ होते हैं।

(cons :a '(:b)) (या (cons :a (cons :b nil))) के लिए एक छोटा हाथ list: (list :a :b) है।

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