यह 'लाम्बा' क्या है जो हर कोई बोलता रहता है। बहुत सारे लोग इसे पसंद करने लगते हैं, लेकिन मैं इससे सभी को इकट्ठा कर सकता हूं, यह एक ही अभिव्यक्ति में कोड की बहुत सारी लाइनों को समेटने का एक तरीका है।
क्या कोई मुझे इसके वास्तविक मूल्य पर बता सकता है?
यह 'लाम्बा' क्या है जो हर कोई बोलता रहता है। बहुत सारे लोग इसे पसंद करने लगते हैं, लेकिन मैं इससे सभी को इकट्ठा कर सकता हूं, यह एक ही अभिव्यक्ति में कोड की बहुत सारी लाइनों को समेटने का एक तरीका है।
क्या कोई मुझे इसके वास्तविक मूल्य पर बता सकता है?
जवाबों:
सीधे शब्दों में कहें, एक मेमना बिना किसी नाम या एक अनाम फ़ंक्शन के एक फ़ंक्शन है। निष्पादन योग्य कोड का एक छोटा टुकड़ा, जिसे चारों ओर से पारित किया जा सकता है जैसे कि यह एक चर था। जावास्क्रिप्ट में:
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
फ़ंक्शन के अपने परिणाम (एक लंबो) वापस आने के बाद भी मेरे पास उस परम तक पहुंच है ।
शब्द "लैम्ब्डा" का उपयोग एक अनाम फ़ंक्शन, आमतौर पर एक क्लोजर को संदर्भित करने के लिए किया जाता है । वे उपयोगी हैं क्योंकि वे आपको ऐसे फ़ंक्शन लिखने की अनुमति देते हैं जो आपके कोड को अनावश्यक रूप से ब्लोट किए बिना अन्य फ़ंक्शन का उपयोग करते हैं। उदाहरण के लिए, रूबी में:
(1..100).select {|num| num % 2 == 0}
यह 1 और 100 के बीच सम संख्याओं वाला एक सरणी बनाएगा। हमें एक स्पष्ट लूप लिखना नहीं है - चयन विधि एक फ़ंक्शन लेती है जो इसे मानों का परीक्षण करने के लिए उपयोग करती है, इसलिए हमें केवल हमारे कस्टम तर्क की आवश्यकता है। यह हमें व्यावहारिक रूप से बिना किसी प्रयास या ओवरहेड के विधि को बहुत अधिक अनुकूलित करने की अनुमति देता है। असल में, हम छोटे फंक्शन्स से रचनाएँ लिख सकते हैं।
यह सिर्फ एक आसान उदाहरण है कि वे क्या कर सकते हैं। डेटा के रूप में कार्यों को पारित करने की क्षमता वास्तव में शक्तिशाली है और कार्यात्मक भाषा प्रोग्रामर नियमित रूप से इसके साथ कुछ वास्तव में आश्चर्यजनक चीजें करते हैं।
"लैम्ब्डा" शायद बहुत कम। लैंबडा कैलकुलस पर एक नजर । यह कार्यात्मक प्रोग्रामिंग में उपयोगी है।
और कार्यात्मक प्रोग्रामिंग अभी तक एक अन्य प्रोग्रामिंग प्रतिमान (जैसे प्रक्रियात्मक, या ऑब्जेक्ट-ओरिएंटेड) है।
.NET में लैम्ब्डा को अक्सर "सिंटैक्टिक शुगर" के रूप में जाना जाता है। वे सीधे कार्यक्षमता को प्रभावित नहीं करते हैं, हालांकि वे लोगों के लिए भाषा का उपयोग करना आसान बनाते हैं।
जब आप उन्हें उपयोग करने की शक्ति को समझ गए होंगे तो मुझे यकीन है कि आप पाएंगे कि आप प्रतिनिधियों / अनाम विधियों का उपयोग करके पुरानी शैली के तरीके की तुलना में कम कोड लिखेंगे।
डॉ। डॉब्स जर्नल में एक उपयोगी लेख है जिसमें लैम्बडा एक्सप्रेशन (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 थे, तो आप लैम्ब्डा एक्सप्रेशन नहीं बल्कि एक सामान्य फ़ंक्शन चाहते हैं। एक फ़ंक्शन ऑब्जेक्ट। "
यदि आपने कभी ऐसे फ़ंक्शन / विधियों के साथ काम किया है जो फ़ंक्शन पॉइंटर्स, डेलिगेट्स, रणनीति या ऑब्जर्वर पैटर्न / ईवेंट हैंडलिंग का उपयोग करते हैं, और अपने आप को सोचा "मैं इस पूरे फ़ंक्शन को सिर्फ एक बार उपयोग करने के लिए लिख रहा हूं - इसे इस विधि को पास करने के लिए ; काश मैं अपने कोड को अव्यवस्थित करने के बजाय बस इसे लिख सकता था "- यही वह जगह है जहाँ आप लैम्बडा फ़ंक्शन का उपयोग कर सकते हैं। इस निर्माण का समर्थन करने वाली भाषाएं आमतौर पर मापदंडों के रूप में गुजरने वाले कार्यों की अवधारणा का लाभ उठाती हैं, विशेष रूप से सूचियों (प्रथम श्रेणी के कार्यों और उच्चतर आदेश कार्यों) के संबंध में। यह कार्यात्मक भाषाओं के लिए विशेष रूप से सच है, जो गणनाओं के लिए स्मृति संशोधन के बजाय फ़ंक्शन संरचना पर निर्भर करते हैं। कुछ मामलों में (पायथन जैसी भाषाओं में),
'लैम्ब्डा' क्वालिफिकेशन शब्द उन दिनों की शब्दावली है, जब कंप्यूटर विज्ञान के प्रकारों को गणित या लॉजिक में प्रशिक्षित किए जाने की संभावना कंप्यूटर साइंस की डिग्री की तुलना में थी। उनमें से कुछ ने 'फंक्शनल प्रोग्रामिंग' नामक एक प्रतिमान को पकाया, जो कि काफी अलग है और काफी शक्तिशाली भी है। AFAIK वह मील का पत्थर है जहाँ यह शब्द प्रयोग में आया था।
गणितज्ञों और तर्कशास्त्रियों को अजीब शब्दों का उपयोग करने के लिए दिया जाता है।
'लैम्ब्डा' वास्तव में गूढ़ लगता है - जैसे कि वे एक बहुत ही अजीब और विशेष चीज हैं। वास्तव में, यदि आप एक वेब ब्राउज़र अनुप्रयोग के लिए जावास्क्रिप्ट लिखते हैं और "var foo = function () {...}" मुहावरे का उपयोग करते हैं, तो आप सभी के साथ लंबो कार्यों का उपयोग कर रहे हैं।
"लंबोदर अभिव्यक्ति एक अनाम फ़ंक्शन है जिसमें अभिव्यक्ति और कथन हो सकते हैं, और इसका उपयोग प्रतिनिधियों या अभिव्यक्ति प्रकार के पेड़ बनाने के लिए किया जा सकता है।
सभी लैम्ब्डा अभिव्यक्तियाँ लैम्बडा ऑपरेटर => का उपयोग करती हैं, जिसे "जाता है" के रूप में पढ़ा जाता है। लैम्ब्डा ऑपरेटर के बाईं ओर इनपुट मापदंडों को निर्दिष्ट करता है (यदि कोई हो) और दाईं ओर अभिव्यक्ति या स्टेटमेंट ब्लॉक रखता है। लैम्ब्डा एक्सप्रेशन x => x * x पढ़ा जाता है "एक्स एक्स एक्स एक्स एक्स के लिए जाता है।"
से MSDN
लैंबडा एक्सप्रेशन के बारे में पूरी जानकारी के लिए, विकिपीडिया पर भी देखें । ( लैम्बडा कैलकुलस और प्रोग्रामिंग लैंग्वेज के लिए नीचे स्क्रॉल करें ।) लैम्बडा एक्सप्रेशन नए नहीं हैं और वे C # का हिस्सा नहीं हैं, लेकिन कुछ ऐसा है जो लगभग 80 साल पहले कंप्यूटिंग में पेश किया गया था! लैम्ब्डा अभिव्यक्ति कार्यात्मक प्रोग्रामिंग का आधार है।
यह मूल्य है? खैर, यह देखते हुए कि यह वास्तव में काफी पुराना है, मैं कहूंगा: गणना करने वाले किसी भी व्यक्ति के लिए बहुत मूल्यवान।
यदि आप जावा में हैं, तो आपने पिछले कुछ महीनों में लैम्ब्डा या क्लोजर के बारे में बहुत कुछ सुना है, क्योंकि इस फीचर को जावा 7 में जोड़ने के लिए अलग-अलग प्रस्ताव थे। हालांकि, मुझे लगता है कि कॉमेडी ने इसे गिरा दिया। प्रस्तावों में से एक नील Gafter से है और यहाँ महान विस्तार से समझाया गया है: javac.info । इससे मुझे उपयोग के मामलों और फायदों को समझने में मदद मिली (विशेषकर आंतरिक कक्षाओं में)
आपको यहां शुरू करने के लिए आपको (सी # लैम्ब्डा के बारे में) जानने की जरूरत है:
लैम्ब्डा अभिव्यक्ति
जावा लैम्ब्डा के लिए, यह एक अच्छा प्रारंभिक बिंदु हो सकता है:
http://rodrigouchoa.wordpress.com/2014/09/10/java-8-lambda-expressions-tutorial/
हां, यह कोड की बहुत सारी लाइनों को एक एकल अभिव्यक्ति में रटने का एक तरीका है। लेकिन इस तरह के कुशल cramming होने के नाते, यह आपके प्रोग्राम को संरचित करने के कुछ नए तरीकों को सक्षम बनाता है।
अक्सर कोई प्रतिनिधि या कॉलबैक लिखने से बचता है और प्रक्रियात्मक शैली में वापस लौटता है, क्योंकि यह एक अभिव्यक्ति के लिए नए कार्यों या कक्षाओं की घोषणा करने के लिए बहुत अधिक काम है।
लैम्ब्डा एक्सप्रेशंस कॉलिंस का उपयोग करने के लिए सबसे अच्छे कार्यों के लिए भी सार्थक बनाते हैं, जिससे कोड अधिक स्पष्ट हो सकता है। शायद नहीं।