एक फ़ंक्शन का नाम क्या है जो कोई तर्क नहीं लेता है और कुछ भी नहीं लौटाता है? [बन्द है]


80

जावा 8 के java.util.functionपैकेज में, हमारे पास:

  • कार्य : एक तर्क लेता है, एक परिणाम उत्पन्न करता है।
  • उपभोक्ता : एक तर्क लेता है, कुछ नहीं पैदा करता है।
  • आपूर्तिकर्ता : कोई तर्क नहीं लेता है, एक परिणाम पैदा करता है।
  • ... : अन्य मामले आदिम, 2 तर्क आदि से निपटने के ...

लेकिन मुझे " कोई तर्क नहीं, कुछ नहीं पैदा करता है " मामले को संभालने की आवश्यकता है ।

इसमें इसके लिए कुछ भी नहीं है java.util.functionnal

तो, सवाल यह है:

' एक फ़ंक्शन का क्या नाम है जो कोई तर्क नहीं लेता है और कुछ नहीं लौटाता है '?

जावा 8 में, इसकी परिभाषा यह होगी:

@FunctionalInterface
public interface InsertANameHere {
    void execute();
}

निष्पादनकर्ता पहले से मौजूद है और इसका एक अन्य उद्देश्य है: " एक वस्तु जो प्रस्तुत किए गए कार्यों को निष्पादित करती है "। हस्ताक्षर मेल नहीं खाता ( execute(Runnable):void) और एक कार्यात्मक इंटरफ़ेस भी नहीं है

रनेबल मौजूद है, लेकिन यह थ्रेडिंग संदर्भ से दृढ़ता से जुड़ा हुआ है:

  • पैकेज है java.lang, नहीं java.util.function
  • Javadoc में कहा गया है: " Runnable इंटरफ़ेस को किसी भी वर्ग द्वारा लागू किया जाना चाहिए, जिनके इंस्टेंस को एक थ्रेड द्वारा निष्पादित किया जाना है "।
  • "रननेबल" नाम एक थ्रेड के अंदर कुछ रनिंग कोड का सुझाव देता है।

28
कोई तर्क लेता है, कुछ भी नहीं पैदा करता है "लेकिन वहाँ के लिए कुछ भी नहीं है" ""। - Runnable ?
user11153

11
मुझे लगता है कि Runnableइस बिंदु पर javadoc पुराना है, क्योंकि एक Runnable का उपयोग अन्य वर्गों द्वारा भी किया जाता है Thread( Executorउदाहरण के लिए)।
SpaceTrucker

13
@superbob का मतलब यह नहीं है कि Runnables केवल s के .run()द्वारा हो सकता है Thread। वास्तव में वे बहुत आम तौर पर सवाल में वर्णित उद्देश्य के लिए उपयोग किया जाता है
blgt

5
@superbob यह प्रारंभिक उद्देश्य था, लेकिन जावा 8 के बाद से यह कार्यात्मक इंटरफ़ेस के रूप में "रेट्रोफिटेड" था। तो यही कारण है कि आपको java.util.function पैकेज में कुछ नहीं मिला ।
14:11 बजे user11153

5
सेमी-स्नार्क: इंप्योरफंटियन क्योंकि यह निश्चित रूप से केवल साइड इफेक्ट्स पर निर्भर करता है, अन्यथा यह एक नो-ऑप है। ( en.wikipedia.org/wiki/Pure_function#Impure_functions ) अधिक सीरियस: इम्पेरेटिव (कुछ करें), जो कम से कम शून्य निष्पादन के शब्दार्थों से मेल खाएगा ();
क्रिस्टियन एच

जवाबों:


71

जावा की पसंद यह करने के लिए है कि हर तरह के नाम के लिए एक अलग नाम बेवकूफ था। यह बिल्कुल अनुकरण करने लायक नहीं है। हालांकि, अगर आप अगर चाहिए स्थिरता की खातिर, या आप बहुत सामान्य पुस्तकालय कोड लिख रहे हैं, कोनराड के सुझाव अच्छे हैं। मैं Procedureरिंग में फेंक सकता हूं ।

छद्म कार्यात्मक प्रतिमान का उपयोग करने का मतलब यह नहीं है कि सामान्य नामकरण सिद्धांतों को खिड़की से बाहर जाना चाहिए। इंटरफेस को लगभग हमेशा उनके नाम पर रखा जाना चाहिए जो वे करते हैं , न कि कुछ सामान्य वाक्यात्मक विचार के बाद। यदि फ़ंक्शन को पूर्ववत स्टैक में रखा जाता है, तो उन्हें नाम दिया जाना चाहिए UndoFunction। यदि उन्हें GUI घटनाओं से बुलाया जाता है, तो उन्हें नाम दिया जाना चाहिए GUIEventHandler। दोस्तों बुरे नामकरण सम्मेलनों को खत्म न होने दें।


Procedureठीक भी है। संदर्भ के लिए, मैं एक सामान्य पुस्तकालय विकसित कर रहा हूं जिसे इस तरह की "संरचना" को संभालने की आवश्यकता है।
सुपरबॉब

18
मुझे Procedureअपने पास्कल दिनों से पसंद है। ए Procedureके साइड इफेक्ट्स हैं, एक Functionनहीं। चूंकि आप एक मूल्य नहीं लौटाते हैं, केवल एक चीज जो कर सकती है, उसका साइड इफेक्ट हो सकता है।
स्पेंसर रथबुन

मैं उपयोग करने के लिए इच्छुक हो सकता है ProcedureRIR<T1,T2>के लिए void proc(T1, int, T2)शायद नहीं बल्कि प्रकार के हर संभव संयोजन में रटना करने की कोशिश कर की तुलना में मांग पर उनमें से ज्यादातर बनाने - अन्य प्रकारों के लिए, और इसी तरह।
सुपरकैट

1
वास्तव में, वास्तविक कार्यात्मक प्रोग्रामिंग आमतौर पर हंगेरियन शैली के नामकरण को प्रोत्साहित नहीं करते हैं। यह कार्यात्मक के बजाय ऊ प्रतिमान की मानसिकता अधिक है।
स्लीपबेटमैन

3
If the functions are placed into an undo stack, they should be named UndoFunction.फ़ंक्शन का नामकरण और इसे एक अलग प्रकार देने के बीच हालांकि एक अंतर है। कार्यात्मक शैली में आप एक नहीं बनाता UndoFunctonक्योंकि अब आप इसे करने के लिए पारित नहीं हो सकता प्रकार flip, curry, compose, filter, map, आदि मेरी राय में है कि असली कारण जावा के अलग-अलग नाम अलग arities साथ कार्यों देने के लिए निर्णय बेवकूफ है। बेशक, यदि आप साइड इफेक्ट्स का उपयोग करने जा रहे हैं, तो इसे कॉल करें; आपने पहले ही रचना को खिड़की से बाहर फेंक दिया और आप यकीनन कार्यों का उपयोग नहीं कर रहे हैं।
डोभाल

33

जावा दुनिया में, इसे कहा जाता है Runnable। C # दुनिया में, इसे कहा जाता है Action

लेकिन, एक बेहतर नाम है जो अच्छी तरह से चीजों के एक बड़े दृश्य के भीतर फिट बैठता है।

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

तो, जावा में, मेरे पास कार्यात्मक इंटरफेस का एक सेट है जिसे मैं Procedureएस कहता हूं , जिसे निम्नानुसार परिभाषित किया गया है:

public interface Procedure
{
    void invoke();
}

public interface Procedure1<T1>
{
    void invoke( T1 argument1 );
}

... (आपको चित्र मिल जाएगा।)

और मेरे पास भी Functionएस नामक इंटरफेस का एक समान सेट है , इसी तरह से परिभाषित किया गया है, जिसमें पहला जेनेरिक पैरामीटर रिटर्न प्रकार है:

public interface Function<R>
{
    R invoke();
}

public interface Function1<R,T1>
{
    R invoke( T1 argument1 );
}

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

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

संशोधन 2017-11-10:

आप पूछ सकते हैं, Function1<R,T1>इसके बजाय क्यों Function1<T1,R>? यह किसी भी तरह से जा सकता है, लेकिन मेरे पास बाईं ओर वापसी मूल्यों के लिए एक प्राथमिकता है क्योंकि मैं 'कन्वर्ट-से' (गंतव्य-से-स्रोत) नामकरण कन्वेंशन का अनुसरण करना पसंद करता हूं, जो 'कन्वर्ट-टू' (स्रोत-से) के विपरीत है -डॉस्टिनेशन) कन्वेंशन। (जो एक कन्वेंशन से अधिक एक दुर्घटना है, वास्तव में, इस अर्थ में कि शायद, किसी ने भी इसे कभी भी कोई विचार नहीं दिया, क्योंकि अगर वे इसे किसी भी विचार को देते थे, तो वे 'कन्वर्ट-से' सम्मेलन में पहुंचे थे। )

मैंने इसके बारे में जोएल स्पॉल्स्की - मेकिंग रोंग कोड लुक गलत में पढ़ा , यह एक बहुत लंबा लेख है, जिसे मैं इसकी संपूर्णता में पढ़ने की सलाह देता हूं, लेकिन अगर आप सीधे मामले में कूदना चाहते हैं, तो 'TypeFromType' की खोज करें, लेकिन आपको टीएल; डीआर, यह विचार देना myint = intFromStr( mystr )बेहतर है myint = strToInt( mystr ), क्योंकि पहले मामले में प्रकारों के नाम संबद्ध मूल्यों के करीब हैं, इसलिए आप आसानी से देख सकते हैं कि 'int' 'int' के साथ मेल खाता है 'str' का मिलान 'str' के साथ होता है।

इसलिए, विस्तार से, मैं चीजों को उस तरह से क्रमबद्ध करता हूं जिस तरह से वे कोड में दिखाई देने वाले हैं।


1
यह समाधान वास्तव में अच्छा है, यह जावा के अपने आपूर्तिकर्ता, उपभोक्ता, BiFunction, ... की तुलना में और भी अधिक बुलेटप्रूफ लगता है, क्योंकि यह सब कुछ केवल दो अवधारणाओं के लिए देता है। यह मुझे याद दिलाता है @Karl Bielefeldt ने " जावा की पसंद को करने के बारे में उत्तर दिया जो कि इस तरह से होता है कि हर तरह के नाम के लिए एक अलग नाम [कि] बेवकूफ था "। केवल "नकारात्मक पक्ष" यह है कि यह आदिम प्रकार और उनके संयोजन (DoubleToLongFunction, ToLongBiFunction, ... जैसे मज़ेदार सामान) को संभालता नहीं है। लेकिन आदिम एक और चिंता का विषय है ...
सुपरबॉब

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

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

ऐसा क्यों नहीं है Function1<T1, R>?
1

@ErikE यह एक बहुत अच्छा प्रश्न है, और मैंने इसका उत्तर देने के लिए अपनी पोस्ट में संशोधन किया।
माइक नकिस

18

क्यों नहीं Command? यह देखते हुए कि यह कोई डेटा नहीं लेता है और कोई डेटा नहीं देता है, लेकिन यह मानते हुए कि इसे कॉल करने से कुछ प्रभाव पड़ता है (अन्यथा यह वास्तव में व्यर्थ होगा), मुझे लगता है कि यह लगभग एक ही चीज़ है जो कर सकता है - एक कार्रवाई में आग लगाइए, कुछ हो सकता है।

जिसमें से बोलते हुए, Action.NET में एक सामान्य प्रतिनिधि भी है । जावा के विपरीत Consumerयह 0 से 16 तर्क तक ले सकता है; दूसरे शब्दों में, इसका सबसे सरल संस्करण कोई नहीं लेता है - MSDN देखें ।

और चूंकि नाम का अर्थ "उपभोग" करने के लिए कुछ भी नहीं है, इसलिए यह एक अच्छा नाम पसंद भी लगता है।


1
Commandअच्छा है। इसे कमांड पैटर्न के साथ भ्रमित किया जा सकता है लेकिन इसका समाधान हो सकता है।
सुपरबॉब

7
मुझे Actionइससे ज्यादा पसंद है Command। एक कमांड कुछ ऐसा लगता है जो प्राप्त और मूल्यांकन किया जाता है, जबकि इसके दुष्प्रभावों के लिए एक कार्रवाई निष्पादित होती है।
बरगी

7
उम्म ... यह एक कमांड पैटर्न कैसे नहीं हो सकता है? आपने वास्तव में कमांड इकाई का निर्माण किया है! यहां तक ​​कि यह परंपरागत रूप से नामित execute()पद्धति भी है। 0_o '
हिजरी

1
कार्रवाई का सुझाव दें, क्योंकि यह एक सामान्य (और अच्छा) स्विंग इंटरफ़ेस है। आज्ञा वाजिब है।
user949300 16

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