यह 'लाम्बा' क्या है जो हर कोई बोलता रहता है।


93

यह 'लाम्बा' क्या है जो हर कोई बोलता रहता है। बहुत सारे लोग इसे पसंद करने लगते हैं, लेकिन मैं इससे सभी को इकट्ठा कर सकता हूं, यह एक ही अभिव्यक्ति में कोड की बहुत सारी लाइनों को समेटने का एक तरीका है।

क्या कोई मुझे इसके वास्तविक मूल्य पर बता सकता है?


16
क्या मैं उत्तरदाताओं को इंगित कर सकता हूं कि प्रश्नकर्ता कहीं उल्लेख नहीं करता है ।net


क्रैकिंग सवाल। पूछने के लिए धन्यवाद।
मूंगफली

लैम्ब्डा कार्यात्मक प्रोग्रामिंग की दुनिया से संबंधित है (घोषणात्मक प्रोग्रामिंग)।
आरबीटी

जवाबों:


179

बिना नाम के कार्य

सीधे शब्दों में कहें, एक मेमना बिना किसी नाम या एक अनाम फ़ंक्शन के एक फ़ंक्शन है। निष्पादन योग्य कोड का एक छोटा टुकड़ा, जिसे चारों ओर से पारित किया जा सकता है जैसे कि यह एक चर था। जावास्क्रिप्ट में:

function () {}; // very simple

आइए अब देखते हैं कि इन मेमनों के लिए कुछ उपयोग क्या हैं।

सार बॉयलरप्लेट कोड

लैम्बडा का उपयोग बॉयलरप्लेट कोड को दूर करने के लिए किया जा सकता है। उदाहरण के लिए लूप्स। हम दिन भर लिखने forऔर whileलूप करने के आदी हैं। लेकिन यह कोड है जो लिखा नहीं जाता है। हम लूप के अंदर कोड निकाल सकते हैं, लूप का सबसे महत्वपूर्ण हिस्सा है, और बाकी को अलग कर सकते हैं:

for (var i=0; i<array.length; i++) {
    // do what something useful with array[i]
}

forEachसरणी वस्तुओं का उपयोग करके , बन जाता है:

array.forEach(function (element, index) {
   // do something useful with element
   // element is the equivalent of array[i] from above
});

उपरोक्त अमूर्त forEachउतने उपयोगी नहीं हो सकते हैं, लेकिन अन्य उच्च क्रम के कार्य हैं, जैसे , कि बहुत अधिक उपयोगी कार्य करते हैं। उदाहरण के लिए filter:

var numbers = [1, 2, 3, 4];
var even    = [];

// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
        even.push(numbers[i]);
    }
}

alert(even);

// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
    return number % 2 === 0;
});

alert(even);

कोड निष्पादन में देरी

कुछ वातावरणों में, जिसमें घटना की अवधारणा उपलब्ध है, हम लैंबडास का उपयोग उन घटनाओं पर प्रतिक्रिया करने के लिए कर सकते हैं जो किसी समय में हो सकती हैं।

window.onload = function () {
    alert("Loaded");
};

window.setTimeout(function () {
    alert("Code executed after 2 seconds.");
}, 2000);

यह कुछ अन्य तरीकों से किया जा सकता था, लेकिन वे क्रियात्मक हैं। उदाहरण के लिए, जावा में Runnableइंटरफ़ेस है।

कार्यों का कारक

इस बिंदु तक, हमने केवल लैम्ब्डा का उपयोग ज्यादातर सिंटैक्टिक शुगर क्षमताओं के लिए किया। लेकिन ऐसी परिस्थितियां हैं जहां लंबोदर बहुत अधिक उपयोगी हो सकते हैं। उदाहरण के लिए हमारे पास ऐसे कार्य हो सकते हैं जो लैम्ब्डा लौटाते हैं। मान लें कि हमारे पास एक फ़ंक्शन है जो हम चाहते हैं कि इसके रिटर्न मान कैश किए जाएं।

var users = [];
var getUser = function (name) {
    if (! users[name]) {
        // expensive operations to get a user. Ajax for example
        users[name] = user_from_ajax;
    }

    return users[name];
};

बाद में, हम देख सकते हैं कि हमारे पास एक समान कार्य है:

var photos = [];
var getPhoto = function (name) {
    if (! photo[name]) {
        // expensive operations to get a user. Ajax for example
        photos[name] = photo_from_ajax;
    }

    return photos[name];
};

वहाँ स्पष्ट रूप से एक पैटर्न है, तो चलो इसे दूर करते हैं। आइए संस्मरण का उपयोग करें ।

/**
 * @param {Array}     store Data structure in which we cache lambda's return values
 * @param {Function}  lambda
 * @return {Function} A function that caches the result of calling the lambda param
 */
var memoize = function (store, lambda) {
    // return a new lambda
    return function (name) {
        if (! store[name]) {
            // Execute the lambda and cache the result
            store[name] = lambda(name);
        }

        return store[name];
    };
};

var getUsers = memoize([], function (name) {
    // expensive operations to get a user. Ajax for example
});

var getPhotos = memoize([], function (name) {
    // expensive operations to get a photo. Ajax for example
});

जैसा कि आप देख सकते हैं, लैम्ब्डा का उपयोग करके, हम कैशिंग / मेमोइज़ेशन लॉजिक को दूर करने में सक्षम थे। यदि अन्य उदाहरण के लिए कुछ वर्कअराउंड थे, तो मेरा मानना ​​है कि अन्य तकनीकों का उपयोग करके इस विशेष समस्या को मुश्किल से हल किया गया है। हम एक ही स्थान पर कुछ महत्वपूर्ण बॉयलरप्लेट कोड निकालने में कामयाब रहे। यह उल्लेख करने के लिए नहीं कि हमें usersऔर photosवैश्विक चर से छुटकारा मिल गया ।

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

पायथन लैम्बडा उपयोग के उदाहरण के रूप में। उपरोक्त कोड जिसमें हमने सम संख्याओं को फ़िल्टर किया है उसे इस तरह से पायथन में दर्शाया जा सकता है:

filter(lambda x: x % 2 == 0, [1, 2, 3, 4])

वैसे भी, लंबोदर बिना बंद किए शक्तिशाली नहीं हैं। क्लोज़र वही है जो लंबोदर की अवधारणा को इतना शक्तिशाली बनाता है। अपने संस्मरण उदाहरण में मैंने पैराम के चारों ओर एक क्लोजर बनाने के लिए क्लोजर का उपयोग किया है store। इस तरह, memoizeफ़ंक्शन के अपने परिणाम (एक लंबो) वापस आने के बाद भी मेरे पास उस परम तक पहुंच है ।


3
वाह आपने बहुत समय लगा दिया।
mk12

4
@ Mk12, उत्तर के वास्तविक लेखन में, वास्तव में नहीं। इस सामान को सीखने में, हाँ, जब से मैंने शुरू किया है, तब से कुछ समय हो गया है :)
आयनोन जी। स्टेन

अच्छा जवाब लेकिन "कार्यात्मक इंटरफेस" (जावा बिंदु से) के बारे में गुम जानकारी।
djangofan 16

आपके "सार बॉइलरप्लेट कोड" में वे "===" ऑपरेटर क्या हैं?
डॉन '


19

शब्द "लैम्ब्डा" का उपयोग एक अनाम फ़ंक्शन, आमतौर पर एक क्लोजर को संदर्भित करने के लिए किया जाता है । वे उपयोगी हैं क्योंकि वे आपको ऐसे फ़ंक्शन लिखने की अनुमति देते हैं जो आपके कोड को अनावश्यक रूप से ब्लोट किए बिना अन्य फ़ंक्शन का उपयोग करते हैं। उदाहरण के लिए, रूबी में:

(1..100).select {|num| num % 2 == 0}

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

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


6
शायद आपको यह जोड़ना चाहिए कि पाइप के भीतर की चीज पैरामीटर है। मैं इन लोगों में से एक हूं, जिन्हें माणिक पढ़ने में परेशानी होती है।
Skurmedel

यह एक अच्छा जवाब है। इयोनुत को मेरे वोट मिलने का एकमात्र कारण यह है कि उन्होंने हमें बताया कि हमें लैंबडास के बारे में (विस्तार से) क्यों ध्यान रखना चाहिए।
फ्रैंक शीयर

मैं इस बात से सहमत नहीं होता कि लैंबडास आमतौर पर बंद होते हैं।
jwg

6

"लैम्ब्डा" शायद बहुत कम। लैंबडा कैलकुलस पर एक नजर । यह कार्यात्मक प्रोग्रामिंग में उपयोगी है।

और कार्यात्मक प्रोग्रामिंग अभी तक एक अन्य प्रोग्रामिंग प्रतिमान (जैसे प्रक्रियात्मक, या ऑब्जेक्ट-ओरिएंटेड) है।


5
फिर लोग "लैम्ब्डा" के बारे में बात करते हैं, सबसे अधिक संभावना है कि वे अनाम फ़ंक्शन, फ़ंक्शन पॉइंटर्स, क्लोजर या कुछ इसी तरह की बात कर रहे हैं। लगभग कभी भी असली लैम्ब्डा कैलकुलस चीज़ का उल्लेख नहीं किया जाता है।
J-16 SDiZ

खुशी है कि आपने लैम्ब्डा कैलकुलस का उल्लेख किया है। +1।
RBT

5

.NET में लैम्ब्डा को अक्सर "सिंटैक्टिक शुगर" के रूप में जाना जाता है। वे सीधे कार्यक्षमता को प्रभावित नहीं करते हैं, हालांकि वे लोगों के लिए भाषा का उपयोग करना आसान बनाते हैं।

जब आप उन्हें उपयोग करने की शक्ति को समझ गए होंगे तो मुझे यकीन है कि आप पाएंगे कि आप प्रतिनिधियों / अनाम विधियों का उपयोग करके पुरानी शैली के तरीके की तुलना में कम कोड लिखेंगे।


1
मुझे नहीं लगता कि किसी ने .NET का उल्लेख किया है, इसलिए ओपी शायद अधिक सामान्य उत्तर के साथ बेहतर है।
मॉल्फ

2
यही कारण है कि मैंने .net के बारे में जवाब देकर स्पष्ट किया है। यदि अन्य लोग अपनी भाषा के कार्यान्वयन के साथ चहकते हैं तो q और कई लोगों को उनकी भाषा की पसंद से कोई फर्क नहीं पड़ता है।
redsquare

यह उत्तर इस तरह पढ़ता है जैसे आपने लंबोदर के बारे में कुछ सुना है, लेकिन आप खुद उन्हें अभी तक नहीं समझते हैं।
jwg

2

डॉ। डॉब्स जर्नल में एक उपयोगी लेख है जिसमें लैम्बडा एक्सप्रेशन (C ++ के संदर्भ में लेकिन मुझे लगता है कि आप सिद्धांतों को किसी भी भाषा में लागू कर सकते हैं) प्रस्तुत करते हैं।

जैसा कि लेख कहता है: "एक लंबोदर अभिव्यक्ति एक उच्च कॉम्पैक्ट अभिव्यक्ति है जिसे एक अलग वर्ग / फ़ंक्शन परिभाषा की आवश्यकता नहीं है।"

इसलिए लिस्टिंग के बजाय DDJ से 1 और 2 की लिस्टिंग के उदाहरणों का उपयोग करें :

std::for_each( vec.begin(), vec.end(), print_to_stream<std::string>(std::cout));

जिसके लिए अलग वर्ग की परिभाषा की आवश्यकता है जैसे:

template <typename T, typename Stream> class print_to_stream_t {
  Stream& stream_;
public:
  print_to_stream_t(Stream& s):stream_(s) {}
  void operator()(const T& t) const {
    stream_ << t;
  }
};
template <typename T,typename Stream> 
print_to_stream_t<T,Stream>   print_to_stream(Stream& s) {
  return print_to_stream_t<T,Stream>(s);
}

बूस्ट लैंबडा लाइब्रेरी का उपयोग करके यह बन सकता है:

std::for_each(vec.begin(),vec.end(),std::cout << _1);

जिससे परिभाषा इनलाइन होती है।

लेख में लैम्ब्डा अभिव्यक्तियों के कुछ और अनुप्रयोगों की भी व्याख्या की गई है।

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


2

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


2

'लैम्ब्डा' क्वालिफिकेशन शब्द उन दिनों की शब्दावली है, जब कंप्यूटर विज्ञान के प्रकारों को गणित या लॉजिक में प्रशिक्षित किए जाने की संभावना कंप्यूटर साइंस की डिग्री की तुलना में थी। उनमें से कुछ ने 'फंक्शनल प्रोग्रामिंग' नामक एक प्रतिमान को पकाया, जो कि काफी अलग है और काफी शक्तिशाली भी है। AFAIK वह मील का पत्थर है जहाँ यह शब्द प्रयोग में आया था।

गणितज्ञों और तर्कशास्त्रियों को अजीब शब्दों का उपयोग करने के लिए दिया जाता है।

'लैम्ब्डा' वास्तव में गूढ़ लगता है - जैसे कि वे एक बहुत ही अजीब और विशेष चीज हैं। वास्तव में, यदि आप एक वेब ब्राउज़र अनुप्रयोग के लिए जावास्क्रिप्ट लिखते हैं और "var foo = function () {...}" मुहावरे का उपयोग करते हैं, तो आप सभी के साथ लंबो कार्यों का उपयोग कर रहे हैं।


1

एक लंबोदर अभिव्यक्ति फ़ंक्शन का एक सरल रूप है। विचार यह है कि बाईं ओर के फार्म का कुछ (मापदंडों के बराबर), दाईं ओर (शरीर के बराबर) फॉर्म का कुछ बन जाता है।

उदाहरण के लिए, ग तेज में:

x => x * x

मान को वर्गाकार करने के लिए एक लंबोदर है। रूप का कुछ

x

रूप का कुछ बन जाता है

x * x

0

"लंबोदर अभिव्यक्ति एक अनाम फ़ंक्शन है जिसमें अभिव्यक्ति और कथन हो सकते हैं, और इसका उपयोग प्रतिनिधियों या अभिव्यक्ति प्रकार के पेड़ बनाने के लिए किया जा सकता है।

सभी लैम्ब्डा अभिव्यक्तियाँ लैम्बडा ऑपरेटर => का उपयोग करती हैं, जिसे "जाता है" के रूप में पढ़ा जाता है। लैम्ब्डा ऑपरेटर के बाईं ओर इनपुट मापदंडों को निर्दिष्ट करता है (यदि कोई हो) और दाईं ओर अभिव्यक्ति या स्टेटमेंट ब्लॉक रखता है। लैम्ब्डा एक्सप्रेशन x => x * x पढ़ा जाता है "एक्स एक्स एक्स एक्स एक्स के लिए जाता है।"

से MSDN


4
हाँ, Microsoft सभी को लगता है कि उन्होंने इसका आविष्कार किया है। लैंबडा एक्सप्रेशंस हालांकि, माइक्रोसॉफ्ट से पहले का है। यह एक गणितीय शब्द है जिसे कई प्रोग्रामिंग भाषाओं पर लागू किया गया है। (जो संभव है, क्योंकि गणित को कंप्यूटर की भाषा माना जा सकता है।)
Wim ten Brink

4
ध्यान दें कि यह Microsoft के .Net कार्यान्वयन के लिए विशिष्ट है। यह एक मेमने के सामान्य विचार से बहुत बड़ा विचलन नहीं है, लेकिन मुझे लगता है कि लिस्प में लागू की गई कार्यक्षमता अधिक "मानक" है।
चक

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

0

लैंबडा एक्सप्रेशन के बारे में पूरी जानकारी के लिए, विकिपीडिया पर भी देखें । ( लैम्बडा कैलकुलस और प्रोग्रामिंग लैंग्वेज के लिए नीचे स्क्रॉल करें ।) लैम्बडा एक्सप्रेशन नए नहीं हैं और वे C # का हिस्सा नहीं हैं, लेकिन कुछ ऐसा है जो लगभग 80 साल पहले कंप्यूटिंग में पेश किया गया था! लैम्ब्डा अभिव्यक्ति कार्यात्मक प्रोग्रामिंग का आधार है।

यह मूल्य है? खैर, यह देखते हुए कि यह वास्तव में काफी पुराना है, मैं कहूंगा: गणना करने वाले किसी भी व्यक्ति के लिए बहुत मूल्यवान।


0

यदि आप जावा में हैं, तो आपने पिछले कुछ महीनों में लैम्ब्डा या क्लोजर के बारे में बहुत कुछ सुना है, क्योंकि इस फीचर को जावा 7 में जोड़ने के लिए अलग-अलग प्रस्ताव थे। हालांकि, मुझे लगता है कि कॉमेडी ने इसे गिरा दिया। प्रस्तावों में से एक नील Gafter से है और यहाँ महान विस्तार से समझाया गया है: javac.info । इससे मुझे उपयोग के मामलों और फायदों को समझने में मदद मिली (विशेषकर आंतरिक कक्षाओं में)




-1

हां, यह कोड की बहुत सारी लाइनों को एक एकल अभिव्यक्ति में रटने का एक तरीका है। लेकिन इस तरह के कुशल cramming होने के नाते, यह आपके प्रोग्राम को संरचित करने के कुछ नए तरीकों को सक्षम बनाता है।

अक्सर कोई प्रतिनिधि या कॉलबैक लिखने से बचता है और प्रक्रियात्मक शैली में वापस लौटता है, क्योंकि यह एक अभिव्यक्ति के लिए नए कार्यों या कक्षाओं की घोषणा करने के लिए बहुत अधिक काम है।

लैम्ब्डा एक्सप्रेशंस कॉलिंस का उपयोग करने के लिए सबसे अच्छे कार्यों के लिए भी सार्थक बनाते हैं, जिससे कोड अधिक स्पष्ट हो सकता है। शायद नहीं।

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