क्या एक एकल अभिव्यक्ति एक एकल विधि के साथ अनाम आंतरिक वर्ग से अधिक है?


40

जावा 8 में लंबे समय से प्रतीक्षित लंबोदर भाव के साथ एक नया प्रचार है; हर 3 दिन में उनके साथ एक और लेख दिखाई देता है कि वे कितने शांत हैं।

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

यह जानकर, क्या लैम्ब्डा एक्सप्रेशन जावा में सिंटैक्टिक शुगरिंग से ज्यादा कुछ लाने जा रहे हैं? क्या मैं अधिक शक्तिशाली और लचीली कक्षाएं या लैम्ब्डा अभिव्यक्तियों के साथ अन्य ऑब्जेक्ट-ओरिएंटेड निर्माण कर सकता हूं जो वर्तमान भाषा सुविधाओं के साथ बनाया जाना संभव नहीं है?


30
जब कोई भाषा ट्यूरिंग-पूर्ण होती है, तो प्रत्येक जोड़ा फीचर को सैद्धांतिक रूप से "सिंटैक्टिक शुगर" के रूप में वर्णित किया जा सकता है।
फिलिपिंस

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

2
@ फिलिप: दुर्भाग्य से टिप्पणियों के लिए केवल एक ही अपवोट है, अन्यथा मैं जोर्ग की टिप्पणी को 1000 बार बढ़ाऊंगा। नहीं, यह गलत है कि किसी भी विशेषता को वाक्यगत शर्करा के रूप में वर्णित किया जा सकता है। सिंथेटिक चीनी में नए शब्दार्थ नहीं आते हैं। वास्तव में, AFAIK प्रस्तावित जावा लैम्ब्डा विशेष गुमनाम आंतरिक वर्गों के लिए सिंथेटिक चीनी नहीं हैं क्योंकि उनके पास अलग-अलग शब्दार्थ हैं।
जियोर्जियो

1
@ जियोर्जियो: और उनके पास क्या अलग शब्दार्थ हैं?
user102008

2
@Giorgio: हाँ, पर के रूपांतरण thisमें OuterClass.thisगुमनाम वर्ग में लैम्ब्डा भाव de-sugaring की प्रक्रिया का हिस्सा है।
user102008

जवाबों:


47

tl; dr: जबकि यह ज्यादातर सिंटैक्टिक शुगर है, यह अच्छा है कि सिंटैक्स बहुत सारी चीजें व्यावहारिक बनाता है जो अंत में, ब्रेसिज़ और कोष्ठक की अप्राप्य लाइनों में समाप्त होता था।

खैर, यह वास्तव में अन्य तरीके से है क्योंकि लैम्ब्डा जावा की तुलना में बहुत पुराना है। एक एकल विधि के साथ अनाम आंतरिक वर्ग हैं (थे) निकटतम जावा लैम्ब्डा में आए। यह एक अनुमान है कि कुछ समय के लिए "काफी अच्छा" था, लेकिन बहुत बुरा वाक्यविन्यास है।

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

लेकिन जब तक कि सभी तकनीकी प्रवृत्तियां दिलचस्प और प्रासंगिक होती हैं (क्योंकि यह जेवीएम में भविष्य के अनुकूलन की अनुमति देता है!), वास्तविक लाभ सिंटैक्टिक चीनी भाग का "बस" है।

क्या पढ़ना आसान है:

myCollection.map(new Mapper<String,String>() {
  public String map(String input) {
    return new StringBuilder(input).reverse().toString();
  }
});

या:

myCollection.map(element -> new StringBuilder(element).reverse().toString());

या (लंबोदर के बजाय एक विधि संभाल का उपयोग करके):

myCollection.map(String::toUpperCase);

तथ्य यह है कि आप अंत में एक संक्षिप्त तरीके से व्यक्त कर सकते हैं जो पहले कोड की 5 लाइनें होगी (जिनमें से 3 पूरी तरह से उबाऊ हैं) जो व्यवहारिक है (लेकिन संभव नहीं है, दी गई नहीं है) का एक वास्तविक परिवर्तन लाता है ।


1
मैं सिंटेक्स शुगरिंग भाग से पूरी तरह सहमत हूं; मेरा सवाल नए ऑब्जेक्ट ओरिएंटेड कंस्ट्रक्शन के बारे में था जो केवल लैम्ब्डा एक्सप्रेशन के साथ संभव था; आखिर जावा एक वस्तु-उन्मुख भाषा है। जेनेरिक के साथ तुलना में सोचें, और कैसे उन्होंने जावा में बहुत लचीलापन खरीदा, लचीलापन उनके बिना अस्वीकार्य है।
m3th0dman

7
@ m3th0dman: वास्तव में जेनरिक ने कोई नई क्षमता नहीं जोड़ी। A Listकिसी भी वस्तु को पकड़ सकता है, एक List<String>तार को "केवल" पकड़ सकता है। जेनरिक ने प्रतिबंध (और प्रतिबंधों को औपचारिक बनाने का विकल्प!) जोड़ा , न कि सत्ता में शामिल होने का। जावा 1.1 के बाद से बहुत ज्यादा सब कुछ सिंथेटिक चीनी है। और यह जरूरी नहीं कि बुरी चीज हो।
जोकिम सॉयर

3
@ m3th0dman: वास्तव में जेनरिक ने कोई नई क्षमता नहीं जोड़ी है, क्योंकि जावा में वे केवल एक सिंटैक्टिक चीनी हैं। A List<String>केवल कुछ रिटर्न वैल्यू के आसपास Listकलाकारों के साथ Stringजोड़ा गया है। फिर भी वे बेहद उपयोगी हैं और भाषा को लिखने में अधिक सुविधाजनक बनाते हैं। लैम्ब्डा इसी तरह के मामले हैं।
जान हुदेक

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

1
@ जानहुडेक: ठीक है, वे सिंटैक्टिक चीनी की तुलना में थोड़ा अधिक हैं, क्योंकि संकलक वास्तव में उनका सम्मान करते हैं। क्रम उनके बारे में परवाह नहीं है, यह सच है।
जोआचिम सॉयर

14

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

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


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

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

2

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


1
नीचे क्यों? मैंने जो कहा वह पूरी तरह सही है
user102008

आप जो लिखते हैं वह जावा लैम्ब्डा के लिए एक उचित प्रस्ताव लगता है, लेकिन यह प्रस्ताव एक अलग ( doanduyhai.wordpress.com/2012/07/12/… ) के पक्ष में खारिज कर दिया गया था ।
जियोर्जियो

1
@ जियोर्जियो: मैं कुछ भी "प्रस्ताव" नहीं कर रहा हूं। क्या, वास्तव में, क्या मैंने जो कहा उससे आप असहमत हैं? हां, अभिव्यक्ति के अंदर अलग-अलग दिखेंगे, जैसे हम एक विधि जोड़ देंगे, और हां, thisको परिवर्तित करने की आवश्यकता होगी OuterClass.this। मैंने जो कहा, उसका खंडन नहीं करता है - प्रत्येक लैंबडा अभिव्यक्ति को उस अभिव्यक्ति के बाहर कुछ भी बदलकर बिना शब्दार्थ-समतुल्य अनाम वर्ग अभिव्यक्ति में परिवर्तित किया जा सकता है । मैंने यह नहीं कहा कि अंदर नहीं बदलेगा।
user102008

3
आपने जो कहा वह गलत है। लैम्ब्डा और एनॉन इनर वर्ग के शब्दार्थ बिल्कुल समान नहीं हैं (हालांकि वे समान हैं)। मेरे सिर के ऊपर से, इस परिवर्तन के अर्थ का अर्थ ; और एक आंतरिक वर्ग हमेशा एक वस्तु के एक नए उदाहरण में परिणाम करता है, जबकि एक मेमना या नहीं हो सकता है।
स्टुअर्ट मार्क्स

1
@StuartMarks: नहीं, आपने मेरा उत्तर नहीं पढ़ा। मैंने यह नहीं कहा कि उनमें से प्रत्येक वह सब कुछ कर सकता है जो दूसरे करते हैं। मैंने कहा कि एक लंबोदर का एक समान अनाम वर्ग है जो शब्दार्थ समान है। जैसा कि मैंने पहले ही टिप्पणियों में कहा है, thisलैम्ब्डा में सिंटैक्टिक शुगर का एक हिस्सा है, और शब्दार्थ में अंतर नहीं है। और कार्यान्वयन, कार्यान्वयन में अंतर के बारे में! = शब्दार्थ। वस्तु पहचान में अंतर के बारे में; लैम्बदास की कार्यक्षमता के लिए वस्तु की पहचान अत्यंत स्पर्शनीय है; लैंबडास / एनोन वर्गों की वस्तु पहचान को कोई भी वैसे भी नहीं देखता क्योंकि यह उपयोगी नहीं है।
user102008

1

Joachim Sauer ने पहले ही एक अच्छा काम किया था जो आपको सवाल का जवाब दे रहा था लेकिन केवल उसी चीज पर इशारा करता था जिसे मैं महत्वपूर्ण मानता हूं। चूंकि लम्बदा कोई वर्ग नहीं है, इसलिए उन्हें भी इस तरह संकलित नहीं किया गया है। सभी अनाम आंतरिक वर्गों के परिणामस्वरूप एक .class फ़ाइल का निर्माण होता है, जिसे बदले में ClassLoader द्वारा लोड किया जाना होता है। तो इसके बजाय लैम्ब्डा का उपयोग करने से न केवल आपका कोड और अधिक सुंदर हो जाता है, बल्कि यह आपके संकलित कोड, आपके क्लासलॉडर की मेमोरी पदचिह्न और आपके हार्ड ड्राइव से बिट्स को स्थानांतरित करने में लगने वाले समय को भी कम कर देता है।


-1

नहीं, वे नहीं हैं।

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


1
कार्यात्मक प्रोग्रामिंग ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के लिए पूरी तरह से ऑर्थोगोनल हो सकता है (देखें: स्काला और एफ #)। यह किसी ऐसे व्यक्ति की राय की तरह है जो सिद्धांत पर कार्यात्मक प्रोग्रामिंग को नापसंद करता है।
KChaloux

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