'ज़िप' संग्रह की झूलने वाली पूंछ को अनदेखा क्यों करता है?


12

सी # , स्काला, हास्केल, लिस्प और पायथन में समान zipव्यवहार है: यदि एक संग्रह लंबा है, तो पूंछ को चुपचाप नजरअंदाज कर दिया जाता है।

यह एक अपवाद भी हो सकता है, लेकिन मैंने इस दृष्टिकोण का उपयोग करते हुए किसी भी भाषा के बारे में नहीं सुना।

यह मुझे पहेली है। क्या किसी को कारण पता zipहै कि इस तरह से क्यों बनाया गया है? मैं नई भाषाओं के लिए अनुमान लगाता हूं, ऐसा इसलिए किया जाता है क्योंकि अन्य भाषाएं इस तरह से करती हैं। लेकिन मूल कारण क्या था?

मैं यहां तथ्यात्मक, ऐतिहासिक-आधारित प्रश्न पूछ रहा हूं, न कि अगर कोई इसे पसंद करता है, या यदि यह एक अच्छा या बुरा दृष्टिकोण है।

अद्यतन : अगर मुझसे पूछा जाए कि मुझे क्या करना है, तो मैं कहूंगा - एक अपवाद को फेंक दो, एक सरणी को अनुक्रमित करने के लिए बहुत समान है ("पुरानी" भाषाओं के बावजूद सभी तरह का जादू किया, कैसे सीमा सूचकांक, यूबी, सरणी का विस्तार करें,) आदि)।


10
अगर यह पूंछ एक फनकार को नजरअंदाज नहीं करता है, तो अनंत दृश्यों का उपयोग करना अधिक बोझिल होगा। खासतौर पर तब जब गैर-अनंत सीमा की लंबाई महंगी / जटिल / असंभव थी।
डेडुप्लिकेटर

2
आपको लगता है कि यह अप्रत्याशित और अजीब है। मुझे यह स्पष्ट है और वास्तव में अपरिहार्य लगता है। जब आप असमान लंबाई के संग्रह को ज़िप करना चाहते हैं तो आप क्या करना चाहेंगे ?
किलियन फोथ

@KilianFoth, एक अपवाद फेंक दिया।
ग्रीनल्डमैन

@ डेडप्लिकेटर, अच्छा है। मूक पूंछ ड्रॉप के साथ आप स्वाभाविक रूप से zipWithIndexप्राकृतिक संख्या जनरेटर प्रदान कर सकते हैं । अब, जानकारी का एकमात्र लापता टुकड़ा - इसका कारण क्या था ? :-) (btw। कृपया अपनी टिप्पणी एक उत्तर के रूप में, धन्यवाद) दें।
ग्रीनोल्डमैन

1
पायथन में itertools.izip_longest है, जो प्रभावी रूप से ऑटोपाड ने नोंस के साथ इनपुट समाप्त कर दिया है। जब मैं वास्तव में ज़िप का उपयोग करता हूं, तो मैं इसे अक्सर ज़िप पर चुनता हूं; मैं किसी भी विकल्प के पीछे कारणों को याद नहीं कर सकता, हालांकि। पायथन में @ ग्रीनल्डमैन के मामले के लिए पहले से ही एन्यूमरेट () है, जिसका मैं अक्सर उपयोग करता हूं।
StarWeaver

जवाबों:


11

यह लगभग हमेशा वही होता है जो आप चाहते हैं, और जब यह नहीं होता है, तो आप अपने आप को भर सकते हैं।

मुख्य मुद्दा आलसी शब्दार्थ के साथ है जब आप पहली बार शुरू करते हैं zipतो आपको लंबाई का पता नहीं होता है , इसलिए आप शुरुआत में केवल एक अपवाद नहीं फेंक सकते। आपको पहले सभी सामान्य तत्वों को वापस करना होगा, फिर एक अपवाद फेंकना होगा, जो बहुत उपयोगी नहीं होगा।

यह एक शैली का मुद्दा भी है। इंपीरियल प्रोग्रामर सभी जगह मैन्युअल रूप से सीमा की स्थिति की जाँच करने के आदी हैं। कार्यात्मक प्रोग्रामर ऐसे निर्माणों को प्राथमिकता देते हैं जो डिज़ाइन द्वारा विफल नहीं हो सकते। अपवाद अत्यंत दुर्लभ हैं। यदि किसी फ़ंक्शन के लिए एक उचित डिफ़ॉल्ट वापस करने का कोई तरीका है, तो कार्यात्मक प्रोग्रामर इसे ले जाएगा। संगतता राजा है।


मैं ऐतिहासिक कारणों के बारे में पूछ रहा हूं, न कि मैं क्या कर सकता हूं। दूसरा पैराग्राफ - आप गलत हैं, एक नज़र डालें कि zipवर्तमान में कैसे लागू किया जाता है। थ्रोइंग अपवाद बस "स्टॉप यील्ड" को "थ्रो" में बदल रहा है। तीसरा पैराग्राफ - सीमा से बाहर पहुंचने के लिए खाली तत्व वापस करना विफल नहीं हो सकता है, लेकिन फिर भी मुझे संदेह है कि कोई भी एफपी देव मतदान करेगा यह एक अच्छा डिजाइन है।
ग्रीनल्डमैन

3
मेरा दूसरा पैराग्राफ सभी कार्यान्वयनों पर लागू नहीं होता है, केवल वास्तव में आलसी हैं। यदि आप zipदो अनंत क्रम एक साथ करते हैं, तो आप शुरू में आकार नहीं जानते हैं। तीसरे पैराग्राफ पर, मैंने उचित डिफ़ॉल्ट कहा । इस मामले में खाली लौटना उचित नहीं होगा, जबकि पूंछ को स्पष्ट रूप से गिराना है।
कार्ल बेवेलफेल्ट

आह, मैं आपकी बात को अंत में देखता हूं - आलसी भाषा में अपवाद को फेंकने के साथ यह तकनीकी प्रतिस्थापन नहीं है, यह पूरी तरह से व्यवहार का परिवर्तन है, क्योंकि आपको शुरू में ही एक अपवाद फेंकने की आवश्यकता है, जबकि आप सुविधाजनक होने पर पूंछ को अनदेखा कर सकते हैं।
ग्रीनल्डमैन

3
+1 यह भी एक महान जवाब है, "कार्यात्मक प्रोग्रामर ऐसे निर्माणों को प्राथमिकता देते हैं जो डिजाइन द्वारा विफल नहीं हो सकते" इसलिए यह स्पष्ट रूप से बताता है कि बहुमत के डिजाइन निर्णयों के पीछे सबसे बड़ा प्रेरक है जो कार्यात्मक प्रोग्रामर बनाते हैं। इंपीरियल प्रोग्रामर्स का एक नियम है जो वे कहते हैं कि "बताओ, मत पूछो", एफपी इसे अंतिम डिग्री तक परिणाम की जांच की आवश्यकता के बिना निर्देशों के निरंतर बताने की अनुमति देकर ध्यान केंद्रित करता है, इसलिए हम मध्यवर्ती चरणों को सुनिश्चित करने का प्रयास करते हैं। असफल नहीं हो सकता, क्योंकि संगतता राजा है। बहुत सही कहा।
जिमी हॉफ

12

क्योंकि पूंछ को पूरा करने का कोई स्पष्ट तरीका नहीं है। यह कैसे करना है पर कोई भी विकल्प एक गैर-स्पष्ट पूंछ में परिणाम होगा।

चाल स्पष्ट रूप से आपकी अपेक्षाओं के साथ सबसे लंबे समय तक की लंबाई से मेल करने के लिए अपनी सबसे छोटी सूची को लंबा करना है।

अगर जिप ने आपके लिए ऐसा किया है, तो आप नहीं जान सकते कि यह कौन से मूल्यों को सहज रूप से भर रहा है। क्या इसने सूची को चक्रित किया? क्या यह एक यादगार मूल्य दोहराता है? आपके प्रकार के लिए एक खाली मान क्या है?

इसमें कोई निहितार्थ नहीं है कि जो जिप करता है वह पूंछ को लंबा करने के तरीके का उपयोग कर सकता है, इसलिए ऐसा करने के लिए केवल उचित चीज उपलब्ध मूल्यों के साथ काम करना है जो आपके उपभोक्ता को उम्मीद नहीं है।


यह भी याद रखें कि आप विशिष्ट अच्छी तरह से ज्ञात शब्दार्थों के साथ एक बहुत ही विशिष्ट प्रसिद्ध कार्य का उल्लेख कर रहे हैं। लेकिन इसका मतलब यह नहीं है कि आप एक समान लेकिन थोड़ा अलग कार्य नहीं कर सकते । सिर्फ इसलिए कि एक सामान्य कार्य है x, इसका मतलब यह नहीं है कि आप अपने दिए गए उद्देश्य के लिए तय नहीं कर सकते हैं जिसे आप करना चाहते हैं xऔर y

हालांकि इसका कारण याद रखें और यह कई अन्य सामान्य एफपी शैली के कार्य आम हैं, क्योंकि वे सरल और सामान्यीकृत हैं इसलिए आप उन्हें उपयोग करने के लिए अपना कोड ट्विक कर सकते हैं और वह व्यवहार प्राप्त कर सकते हैं जो आप चाहते हैं। उदाहरण के लिए, C # में आप बस कर सकते हैं

IEnumerable<Tuple<T, U>> ZipDefaults(IEnumerable<T> first, IEnumerable<U> second)
{
    return first.Count() < second.Count()
        ? first.Concat(Enumerable.Repeat(default(T), second.Count() - first.Count())).Zip(second)
        : first.Zip(second.Concat(Enumerable.Repeat(default(U), first.Count() - second.count())))
}

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


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

2
zipनल में भर सकता है, जो अक्सर एक सहज समाधान है। प्रकार पर विचार करें zip :: [a] -> [b] -> [(Maybe a, Maybe b)]। दी, परिणाम प्रकार थोड़ा सा है ^ एच ^ एच काफी अव्यवहारिक है, लेकिन यह आसानी से इसके शीर्ष पर किसी भी अन्य व्यवहार (शॉर्ट कट, अपवाद) को लागू करने की अनुमति देगा।
अमोन

1
@amon: यह बिल्कुल सहज नहीं है, यह मूर्खतापूर्ण है। यह सिर्फ हर तर्क की जाँच की आवश्यकता होगी।
डेडएमजी

4
@amon के पास हर प्रकार का एक अशक्त नहीं है, जो कि मेरा मतलब है mempty, वस्तुओं में स्थान को भरने के लिए अशक्त है, लेकिन आप चाहते हैं कि इसे इंट और अन्य प्रकारों के लिए भी आना चाहिए? निश्चित रूप से, C # के पास default(T)सभी भाषाएँ नहीं हैं, और C # के लिए भी क्या यह वास्तव में स्पष्ट व्यवहार है? मुझे ऐसा नहीं लगता
जिमी हॉफ

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