एक लैम्ब्डा क्या है, और यह क्यों उपयोगी होगा? [बन्द है]


56

अब तक मैंने इसके बारे में सुना:

  • लैम्ब्डा कैलकुलस
  • लैम्ब्डा प्रोग्रामिंग
  • लम्बोदर भाव
  • लैम्ब्डा कार्य करता है

जो सभी कार्यात्मक प्रोग्रामिंग से संबंधित लगता है ...

जाहिरा तौर पर इसे C ++ 1x में एकीकृत किया जाएगा, इसलिए मैं इसे अब बेहतर समझ सकता हूं:

http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

क्या कोई व्यक्ति संक्षेप में बता सकता है कि लंबोदर चीजें क्या हैं और यह कहां उपयोगी हो सकती हैं?


2
ध्यान दें कि शब्दावली ऐतिहासिक रूप से एक अभिव्यक्ति द्वारा प्रस्तुत फ़ंक्शन के बारे में बात करने के लिए एक अच्छा तरीका चाहने से आती है। X + 1 द्वारा दर्शाया गया फ़ंक्शन तब लंबो एक्स लिखा जाता है। x + 1।
१०:१० को

लैम्ब्डा तरीके से, एक फ़ंक्शन दूसरे फ़ंक्शन और / या इनपुट वैल्यू को खाता है, एक और फ़ंक्शन का उत्पादन करता है। यह तब तक जारी रहता है जब तक कोई फ़ंक्शन समाधान का उत्पादन नहीं करता है। इसके अलावा, मगरमच्छ अंडे
एसडी

यह सब मेरे लिए काला अक्षर भैंस बराबर है। मुझे लगता है कि मैं जाऊंगा, मुझे एक मेमना पसंद है, मुझे मेमना पसंद है।

जवाबों:


44
  • लैम्ब्डा कैलकुलस

लैम्ब्डा कैलकुलस 30 के दशक में अलोंजो चर्च द्वारा आविष्कार किया गया एक संगणना मॉडल है। अधिकांश कार्यात्मक प्रोग्रामिंग भाषाओं के वाक्यविन्यास और शब्दार्थ लैम्ब्डा कैलकुलस से प्रत्यक्ष या अप्रत्यक्ष रूप से प्रेरित होते हैं।

अपने सबसे बुनियादी रूप में लैम्ब्डा कैलकुलस के दो ऑपरेशन हैं: एब्सट्रैक्शन (एक (अनाम) फ़ंक्शन) और एप्लिकेशन (एक फ़ंक्शन लागू करें)। Λ ऑपरेटर का उपयोग करके एब्सट्रैक्शन किया जाता है, लैम्ब्डा पथरी को उसका नाम दिया जाता है।

  • लम्बोदर भाव
  • लैम्ब्डा कार्य करता है

बेनामी फ़ंक्शंस को अक्सर "लंबदा", "लैम्ब्डा फ़ंक्शंस" या "लैम्ब्डा एक्सप्रेशंस" कहा जाता है क्योंकि, जैसा कि मैंने ऊपर कहा, लैंबडा कैलकुलस में अनाम फ़ंक्शन बनाने के लिए λ प्रतीक था (और शब्द lambdaका उपयोग कई लिस्प में अनाम कार्यों को बनाने के लिए किया जाता है एक ही कारण के लिए -based भाषाओं)।

  • लैम्ब्डा प्रोग्रामिंग

यह आमतौर पर इस्तेमाल किया जाने वाला शब्द नहीं है, लेकिन मुझे लगता है कि इसका अर्थ है अनाम कार्यों का उपयोग करना या उच्च-क्रम के कार्यों का उपयोग करके प्रोग्रामिंग करना।


C ++ 0x में लैम्ब्डा के बारे में थोड़ी अधिक जानकारी, उनकी प्रेरणा और वे फंक्शन पॉइंटर्स से कैसे संबंधित हैं (यह बहुत संभवतया एक दोहराव है जो आप पहले से जानते हैं, लेकिन मुझे आशा है कि यह लैम्ब्डा की प्रेरणा को समझाने में मदद करता है और वे कैसे भिन्न होते हैं समारोह के संकेत से):

फ़ंक्शन पॉइंटर्स, जो पहले से ही सी में मौजूद थे, उदाहरण के लिए एक छँटाई फ़ंक्शन के लिए एक तुलना फ़ंक्शन पास करने के लिए काफी उपयोगी हैं। हालाँकि उनकी उपयोगिता की सीमाएँ हैं:

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

इसे हल करने के लिए, C ++ ने "फ़ंक्शन ऑब्जेक्ट्स" या "फ़ंक्शनलर्स" की अवधारणा पेश की। एक फंटर मूल रूप से एक वस्तु है जिसमें एक operator()विधि है। अब हम एक वर्ग को परिभाषित कर सकते हैं CompareByIthElement, जो तर्क iको एक रचनाकार तर्क के रूप में लेता है और फिर दो वैक्टर को तर्क के रूप में operator()विधि की तुलना में ले जाता है । iवें तत्व द्वारा वैक्टर के एक वेक्टर को सॉर्ट करने के लिए अब हम एक CompareByIthElementऑब्जेक्ट iको एक तर्क के रूप में बना सकते हैं और फिर उस ऑब्जेक्ट को सॉर्टिंग फ़ंक्शन में पास कर सकते हैं ।

चूँकि फंक्शन ऑब्जेक्ट्स ऑब्जेक्ट्स होते हैं न कि तकनीकी रूप से फ़ंक्शंस (भले ही वे उनके जैसा व्यवहार करने के लिए हों), आप फंक्शन पॉइंटर पॉइंट को फंक्शन ऑब्जेक्ट के लिए नहीं बना सकते हैं (आप निश्चित रूप से एक फंक्शन ऑब्जेक्ट के लिए पॉइंटर कर सकते हैं, लेकिन यह एक प्रकार होगा CompareByIthElement*और इस तरह एक फ़ंक्शन पॉइंटर नहीं होगा)।

C ++ मानक लाइब्रेरी में अधिकांश कार्य जो तर्कों के रूप में कार्य करते हैं उन्हें टेम्प्लेट का उपयोग करके परिभाषित किया जाता है ताकि वे फ़ंक्शन पॉइंटर्स के साथ-साथ फ़ंक्शन ऑब्जेक्ट्स के साथ काम करें।

अब लंबोदर को:

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

तो इसे ठीक करने के लिए इस लंबोदर को पेश किया गया था। लम्बदा फ़ंक्शन ऑब्जेक्ट्स हैं, न कि फ़ंक्शन पॉइंटर्स। यदि आप एक लैम्ब्डा शाब्दिक का उपयोग करते हैं जैसे [x1, x2](y1,y2){bla}कोड उत्पन्न होता है जो मूल रूप से निम्न कार्य करता है:

  1. एक वर्ग को परिभाषित करें जिसमें दो सदस्य चर ( x1और x2) और operator()तर्कों ( y1और y2) और शरीर के साथ हैं bla
  2. सदस्य चर को सेट करने x1और चर x2के मानों x1और x2वर्तमान में दायरे में वर्ग का एक उदाहरण बनाएं ।

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


क्या अनाम फ़ंक्शन फ़ंक्शन पॉइंटर्स के साथ उपयोग किए जाते हैं? यदि नहीं तो क्या अंतर है?
13

1
@ जोकून: नहीं, अनाम फ़ंक्शन को फ़ंक्शन के मापदंडों के रूप में पारित नहीं किया जा सकता है जो केवल फ़ंक्शन पॉइंटर्स लेते हैं। हालाँकि अधिकांश कार्य जो तर्कों के रूप में कार्य करते हैं उन्हें टेम्प्लेट का उपयोग करके परिभाषित किया जाता है ताकि वे किसी भी प्रकार के फ़ंक्शन ऑब्जेक्ट को तर्क के रूप में ले सकें, न कि केवल फ़ंक्शन पॉइंटर को। यह उन जगहों पर कहना है जहां आप फ़ंक्शन पॉइंटर्स का उपयोग कर सकते हैं ( std::sortउदाहरण के लिए), आप इसके बजाय अनाम फ़ंक्शंस का उपयोग कर पाएंगे। हालाँकि जब किसी फ़ंक्शन को एक अनाम फ़ंक्शन को उसके तर्क के रूप में परिभाषित किया जाता है, तो आपको या तो एक टेम्पलेट का उपयोग करना होगा या std::functionतर्क के प्रकार के रूप में उपयोग करना होगा ।
sepp2k

इसलिए एक फ़ंक्शन पॉइंटर में एक लैम्ब्डा नहीं हो सकता ...
jokoon

1
+1 उत्कृष्ट स्पष्टीकरण - मैं यह पता लगाने में सक्षम नहीं था।
माइकल के

2
मैं इस पर माइकल के साथ हूँ। यह बहुत व्यापक है। +1मुझ से।
sbi

18

मूल रूप से, लैम्ब्डा फ़ंक्शन ऐसे कार्य हैं जो आप "मक्खी पर" बनाते हैं। C ++ 1x में उन्हें कार्यात्मक प्रोग्रामिंग के लिए इसके समर्थन में सुधार करने के लिए इस्तेमाल किया जा सकता है:

std::for_each( begin, end, [](int i){std::cout << i << '\n';} );

यह लगभग एक के समान कोड में परिणाम देगा:

struct some_functor {
  void operator()(int i) {std::cout << i << '\n';}
};

std::for_each( begin, end, some_functor() );

अगर आपको some_functorइसके लिए बस एक कॉल की जरूरत है std::for_each(), तो उस लंबो फंक्शन के कई फायदे हैं:

  • लूप में जो किया जाता है वह सही निर्दिष्ट होता है जहां लूपिंग फ़ंक्शन को कहा जाता है
  • यह आपको कुछ बॉयलर-प्लेट कोड लिखने से राहत देता है
  • कुछ नाम स्थान के दायरे में कोई फ़ंक्टर नहीं है जो हर किसी को कोड को देखकर सोच रहा हो कि यह किस चीज की आवश्यकता है

7

एक लंबो फ़ंक्शन एक अनाम फ़ंक्शन का दूसरा नाम है - अनिवार्य रूप से एक नाम के बिना एक फ़ंक्शन।

आमतौर पर आप इसका उपयोग उन भाषाओं में करते हैं जहाँ आपको केवल एक बार फ़ंक्शन का उपयोग करना होगा। के बजाय उदाहरण के लिए

def add(a, b)
  return a+b

और फिर उस फ़ंक्शन को किसी अन्य फ़ंक्शन में पास करना जैसे कि

reduce(add, [5,3,2])

एक मेमने के साथ आप बस करेंगे

reduce(lambda x, y: a+b, [5,3,2])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.