कार्यात्मक भाषाओं में पसंद की डेटा संरचना को सूचीबद्ध क्यों किया जाता है?


45

अधिकांश कार्यात्मक भाषाएं अपनी प्राथमिक अपरिवर्तनीय डेटा संरचना के रूप में लिंक की गई सूचियों का उपयोग करती हैं। सूची क्यों, और उदाहरण के लिए पेड़ नहीं? पेड़ पथों का पुन: उपयोग भी कर सकते हैं, और यहां तक ​​कि मॉडल सूची भी।



10
@gnat - यह उस प्रश्न का डुप्लिकेट नहीं है। उस प्रश्न का स्वीकृत और सही उत्तर अनिवार्य रूप से "है क्योंकि एक अपरिवर्तनीय लिंक्ड सूची अद्यतन और मूल सूचियों के बीच पूंछ साझा करने की अनुमति देती है", एक उत्तर जिसे इस प्रश्न की पृष्ठभूमि के भाग के रूप में इंगित किया गया है ...
जूल्स

9
स्पष्टीकरण का एक बिंदु यह है कि एक "सूची" (अमूर्त प्रोग्रामिंग अवधारणा) एक "लिंक की गई सूची" (उस अवधारणा का एक विशेष कार्यान्वयन) से अलग है, बहुत कुछ जैसे प्रोग्रामिंग भाषा का विनिर्देश इसके कार्यान्वयन से अलग है। सवाल "कार्यात्मक भाषा सूचियों (अमूर्त प्रोग्रामिंग अवधारणा) का उपयोग उनकी मुख्य डेटा संरचना के रूप में क्यों करती है?" सूक्ष्म रूप से, लेकिन मौलिक रूप से इस सवाल से बहुत अलग है कि "कार्यात्मक भाषाओं X, Y, और Z की आम कार्यान्वयन लिंक सूचियों को उनकी मुख्य डेटा संरचना के रूप में क्यों उपयोग करते हैं?"
आरएम

I scala वेक्टर (जिसे एक पेड़ के रूप में लागू किया गया है) सूची stackoverflow.com/questions/6928327/… को थोड़ा पसंद किया जाता है । व्यवहार में अधिकांश लोग अभी भी सूची का उपयोग करते हैं (जो मैंने देखा है) से।
अकवाल

मैंने स्काला में कुछ कोर्स फंक्शनल प्रोग्रामिंग कोर्स किए और पेड़ों के साथ एक बहुत इस्तेमाल किया। यह सिर्फ इतना है कि उदाहरण के लिए सूची सरल है। पेड़ों का उपयोग प्रदर्शन की समस्याओं के लिए किया जाता है। जैसे ही आप अयोग्य सूची में तत्वों को जोड़ते हैं, आप पुराने पेड़ों के पुन: उपयोग करने वाले अयोग्य पेड़ बना सकते हैं।
बोरजब

जवाबों:


56

क्योंकि सूची पेड़ों की तुलना में सरल हैं। (आप इसे इस तथ्य से तुच्छ रूप से देख सकते हैं कि एक सूची एक पतित वृक्ष है, जहां प्रत्येक नोड में केवल एक ही बच्चा है।)

सामान्य सूची मनमाने आकार की सबसे सरल संभव पुनरावर्ती डेटा संरचना है।

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

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

तो, संक्षेप में: एक आम सूची सबसे सरल संभव लगातार डेटा संरचना है, और अधिक जटिल "डिफ़ॉल्ट" चुनने की आवश्यकता नहीं थी। अन्य विकल्प के रूप में निश्चित रूप से उपलब्ध हैं, उदाहरण के लिए हास्केल के पास सरणियाँ, प्राथमिकता कतारें, नक्शे, ढेर, ट्रेप्स, कोशिशें हैं, और सब कुछ जो आप संभवतः कल्पना कर सकते हैं, लेकिन डिफ़ॉल्ट सरल सामान्य सूची है।


10
हां, क्लीजुर वैक्टर को पेड़ों के रूप में लागू किया जाता है - लेकिन यह ध्यान देने योग्य है कि वे हैश एरे मैप किए गए हैं , न कि आपके बाइनरी data Tree a = Leaf a | Branch a (Tree a) (Tree a)एस। यह आपके "सरलता" तर्क को पुष्ट करता है।
वचगिन

1
एफडब्ल्यूआईडब्ल्यू क्लॉजुर के लगातार वैक्टर को तेज (बड़े आधार के साथ लॉगरिदमिक) और मनमानी तत्वों के उपयोग और अद्यतन के लिए पेड़ों के रूप में कार्यान्वित किया जाता है, मनमाने ढंग से तत्वों के उपयोग और अद्यतन के लिए, वास्तव में प्रति समानांतर समानांतर संचालन के लिए नहीं (अपरिपक्व भाग कुछ का ध्यान रखता है। डिग्री)। अन्य FP भाषाएं एक ही विकल्प बनाती हैं (कभी-कभी विभिन्न प्रकार के पेड़ों के साथ) जब वे उन दोनों (जैसे हास्केल Sequenceया स्काला के Vector) चाहते हैं, लेकिन पेड़ों का उपयोग नहीं करते हैं जब उन्हें केवल पढ़ने की आवश्यकता होती है क्योंकि वे सच्चे निरंतर समय में प्राप्त कर सकते हैं (जैसे हास्केल के Vectorया एफ के माध्यम से नेट का # ImmutableArray)
badcook

1
उदाहरण के लिए pmapक्लोजर में एक वेक्टर पर पिंग अभी भी प्रत्येक तत्व को क्रमिक रूप से एक्सेस करता है; वेक्टर की वृक्ष संरचना आम तौर पर अंतिम उपयोगकर्ता से छिपी होती है।
बैकुंठ

5

वास्तव में, उन सूचियों हैं पेड़! आपके पास दो फ़ील्ड के साथ नोड्स हैं, carऔर cdr, जिसमें अधिक ऐसे नोड्स या पत्तियां हो सकती हैं। केवल एक चीज जो उन पेड़ों को सूचियों में बनाती है, एक रैखिक सूची में अगले नोड के लिंक के रूप में लिंक की व्याख्या करने के लिए सम्मेलन है cdr, और carवर्तमान नोड के मूल्य के रूप में लिंक है।

उस ने कहा, मेरा अनुमान है कि कार्यात्मक प्रोग्रामिंग में लिंक की गई सूचियों का प्रसार पुनरावृत्ति के प्रसार से जुड़ा हुआ है। जब आपके हाथ में केवल लूपिंग निर्माण होता है (पूंछ-) पुनरावृत्ति, आप डेटा संरचनाएं चाहते हैं जो उस के साथ उपयोग करना आसान है; और लिंक की गई सूचियाँ उसके लिए एकदम सही हैं।


5
यह भाषा पर निर्भर करता है। निश्चित रूप से, आप LISP-पसंद में एक पेड़ को लागू कर सकते हैं बुरा कोशिकाओं का उपयोग करके, लेकिन हास्केल में, उदाहरण के लिए, आपको एक पूरी तरह से अलग संरचना की आवश्यकता होगी। और यह भी ध्यान दें कि अधिकांश कार्यात्मक भाषाओं में पूंछ पुनरावृत्ति की तुलना में बहुत अधिक लूपिंग निर्माण होते हैं। मिसाल के तौर पर हास्केल कोर लाइब्रेरीज़, सिलवटों (बाएं और दाएं), स्कैन, पेड़ों पर ट्रैवर्सल्स, चाबियों पर पुनरावृत्तियों और नक्शों के मूल्यों और कई अन्य विशेषज्ञ संरचनाओं को प्रदान करती हैं। ज़रूर, वे पर्दे के पीछे पुनरावृत्ति के साथ लागू होते हैं, लेकिन उपयोगकर्ता को उन्हें काम करने के बारे में सोचने की भी ज़रूरत नहीं है।
जूल्स

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

2
@cmaster जबकि हास्केल छोटी है यह अभी भी 27 साल पुरानी है और कई भाषाओं को प्रभावित किया है (कुछ प्रभावशाली नाम देने के लिए पायथन, जावा और C # सहित)। LISP द्वारा कार्यात्मक प्रोग्रामिंग को पहचानना ALGOL द्वारा अनिवार्य प्रोग्रामिंग को पहचानने जैसा है - दोनों एक लंबा रास्ता तय करते हैं क्योंकि पहचानने योग्य नहीं है। ठीक। लिस्प यकीनन अभी भी प्रासंगिक है, लेकिन मैं इसे 'मुख्य धारा' नहीं मानूंगा और एमएल के प्रकारों सहित बहुत बाद की अंतर्दृष्टि को याद करता हूं।
मैकीज पाइचोटका

1
यदि आप पूरे पेड़ को छूना चाहते हैं, तो आप एक स्पष्ट स्टैक के बिना पुनरावर्ती या पुनरावृत्ति से जुड़े हुए पेड़ों की पूंछ को संसाधित नहीं कर सकते हैं, इसलिए मुझे नहीं लगता कि पूंछ की पुनरावृत्ति का इससे कोई लेना-देना है।
k_g

@MaciejPiechotka न तो पायथन, जावा, और न ही C # को कार्यात्मक भाषाओं के रूप में देखा जा सकता है, वे अनिवार्य हैं और कुछ विशेषताएं जोड़ते हैं जो कार्यात्मक प्रोग्रामिंग से प्रेरित हैं। एक बार जब आप राज्य बदल रहे होते हैं, तो आप कार्यशील प्रोग्रामिंग नहीं, अनिवार्य रूप से अनिवार्य डोमेन के अंदर होते हैं। मैं आपसे सहमत हूँ, हालाँकि, कि LISP निश्चित रूप से मुख्यधारा नहीं है।
सेमास्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.