सिंटेक्स डिज़ाइन - जब कोई तर्क पारित नहीं होता है, तो कोष्ठक का उपयोग क्यों करें?


66

कई भाषाओं में, function_name(arg1, arg2, ...)फ़ंक्शन को कॉल करने के लिए सिंटैक्स का उपयोग किया जाता है। जब हम फ़ंक्शन को बिना किसी तर्क के कॉल करना चाहते हैं, तो हमें करना चाहिए function_name()

मुझे यह अजीब लगता है कि एक संकलक या स्क्रिप्ट दुभाषिया को ()फ़ंक्शन कॉल के रूप में सफलतापूर्वक इसका पता लगाने की आवश्यकता होगी । यदि एक चर को कॉल करने योग्य माना जाता है, function_name;तो पर्याप्त क्यों नहीं होगा?

दूसरी ओर, कुछ भाषाओं में हम कर सकते हैं: function_name 'test';या function_name 'first' 'second';किसी फ़ंक्शन या कमांड को कॉल करने के लिए भी ।

मुझे लगता है कि अगर उन्हें केवल प्राथमिकता के क्रम को घोषित करने की आवश्यकता होती है, और अन्य स्थानों पर वैकल्पिक होते तो कोष्ठक बेहतर होते। उदाहरण के लिए, if expression == true function_name;जैसा होना चाहिए वैसा ही मान्य होना चाहिए if (expression == true) function_name();

मेरी राय में सबसे कष्टप्रद बात यह है कि 'SOME_STRING'.toLowerCase()जब प्रोटोटाइप फ़ंक्शन द्वारा स्पष्ट रूप से कोई तर्क की आवश्यकता नहीं होती है। डिजाइनरों ने सरल के खिलाफ फैसला क्यों किया 'SOME_STRING'.lower?

डिस्क्लेमर: मुझे गलत मत समझो, मुझे सी-सिंटैक्स पसंद है! ;) मैं सिर्फ यह पूछ रहा हूं कि क्या यह बेहतर हो सकता है। क्या ()किसी भी प्रदर्शन लाभ की आवश्यकता होती है, या क्या यह कोड को समझना आसान बनाता है? मैं वास्तव में उत्सुक हूं कि वास्तव में इसका क्या कारण है।


103
यदि आप किसी फ़ंक्शन को किसी अन्य फ़ंक्शन के तर्क के रूप में पास करना चाहते हैं, तो आप क्या करेंगे?
विन्सेन्ट सेवार्ड

30
जब तक मनुष्यों द्वारा कोड को पढ़ने की आवश्यकता है, पठनीयता राजा है।
ट्यूलेंस कोरडोवा

75
यह पठनीयता वाली बात है, आप इसके बारे में पूछते हैं (), फिर भी आपकी पोस्ट में जो if (expression == true)बात सामने आती है, वह कथन है। आप फालतू ()की चिंता करते हैं , फिर भी एक सुपरफुल == true:) का इस्तेमाल करते हैं :)
डेविड अरनो

15
विजुअल बेसिक ने इसकी अनुमति दी
edc65

14
पास्कल में यह अनिवार्य था, आपने केवल उन कार्यों और प्रक्रियाओं के लिए पैरेन्स का उपयोग किया था जो तर्क लेते थे।
रेमकोगर्लिच

जवाबों:


251

प्रथम श्रेणी के कार्यों का उपयोग करने वाली भाषाओं के लिए , यह काफी सामान्य है कि किसी फ़ंक्शन का संदर्भ देने का सिंटैक्स है:

a = object.functionName

जबकि का कार्य बुला कि समारोह है:

b = object.functionName()

aउपरोक्त उदाहरण में उपरोक्त फ़ंक्शन का संदर्भ होगा (और आप इसे करके कॉल कर सकते हैं a()), जबकि bफ़ंक्शन का रिटर्न मान होगा।

हालांकि कुछ भाषाएं बिना कोष्ठक के फ़ंक्शन कॉल कर सकती हैं, यह भ्रमित हो सकता है कि क्या वे फ़ंक्शन को कॉल कर रहे हैं , या केवल फ़ंक्शन का उल्लेख कर रहे हैं।


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

73
@ बर्गी: यह शुद्ध कार्यों के लिए बहुत मायने रखता है! अगर मेरे पास एक फ़ंक्शन है make_listजो एक सूची में अपने तर्कों को पैक करता है, तो f(make_list)फ़ंक्शन को fपास करने या खाली सूची को पारित करने के बीच एक बड़ा अंतर है ।
user2357112

12
@Bergi: फिर भी, मैं अभी भी SATInstance.solveइसे चलाने के प्रयास के बिना किसी अन्य फ़ंक्शन के लिए कुछ अन्य अविश्वसनीय रूप से महंगा शुद्ध कार्य करने में सक्षम होना चाहता हूं । यह भी वास्तव में अजीब बनाता है someFunctionकि क्या someFunctionशुद्ध होने की घोषणा के आधार पर कुछ अलग करता है। उदाहरण के लिए, अगर मैं (स्यूडोकोड) है func f() {return g}, func g() {doSomethingImpure}और func apply(x) {x()}है, तो apply(f)कहता है f। अगर मैं फिर घोषित करता हूं कि fशुद्ध है, तो अचानक apply(f)पास हो जाता gहै apply, और applyकॉल gकरता है और कुछ अशुद्ध करता है।
user2357112

6
@ user2357112 मूल्यांकन रणनीति शुद्धता से स्वतंत्र है। जब संभव है (लेकिन शायद अजीब है) का मूल्यांकन करने के लिए एक एनोटेशन के रूप में कॉल के सिंटैक्स का उपयोग करना, हालांकि यह परिणाम या इसकी शुद्धता को नहीं बदलता है। अपने उदाहरण के बारे में apply(f), अगर gअशुद्ध है (और applyसाथ ही?) तो पूरी चीज अशुद्ध है और निश्चित रूप से टूट जाती है।
बरगी

14
इसके उदाहरण पायथन और ईसीएमएस्क्रिप्ट हैं, जिनमें से दोनों में वास्तव में "विधियों" की एक मुख्य अवधारणा नहीं है, इसके बजाय आपके पास एक नामित संपत्ति है जो एक अनाम प्रथम श्रेणी के फ़ंक्शन ऑब्जेक्ट को लौटाती है और फिर आप उस अनाम प्रथम श्रेणी फ़ंक्शन को कॉल करते हैं। विशेष रूप से, पायथन और ईसीएमएस्क्रिप्ट दोनों में, कहा foo.bar()जाता है कि एक ऑपरेशन " barऑब्जेक्ट का कॉल विधि foo" नहीं है, बल्कि दो ऑपरेशन हैं, " barऑब्जेक्ट के क्षेत्र को निष्क्रिय करना foo और फिर उस फ़ील्ड से वापस आ गई वस्तु को कॉल करना"। तो, .है फ़ील्ड चयनकर्ता ऑपरेटर और ()है कॉल ऑपरेटर और वे स्वतंत्र हैं।
जोर्ग डब्ल्यू मित्तग

63

वास्तव में, स्काला इसे अनुमति देता है, हालांकि इसके बाद एक सम्मेलन होता है: यदि विधि के दुष्प्रभाव हैं, तो वैसे भी कोष्ठक का उपयोग किया जाना चाहिए।

एक संकलक लेखक के रूप में, मैं कोष्ठकों की गारंटीकृत उपस्थिति को काफी सुविधाजनक मानूंगा; मुझे हमेशा पता होगा कि यह एक विधि कॉल है, और मुझे विषम मामले के लिए द्विभाजन में निर्माण नहीं करना होगा।

एक प्रोग्रामर और कोड रीडर के रूप में, कोष्ठक की उपस्थिति कोई संदेह नहीं छोड़ती है कि यह एक विधि कॉल है, भले ही कोई पैरामीटर पारित न हो।

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


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

कोष्ठकों की उपस्थिति में कोई संदेह नहीं है कि यह एक विधि कॉल है जिसे मैं पूरी तरह से सहमत हूं। मैं अपनी प्रोग्रामिंग भाषाओं को निहित से अधिक स्पष्ट पसंद करता हूं।
कोरी ओगबर्न

20
स्काला वास्तव में इससे थोड़ा अधिक सूक्ष्म है: जबकि अन्य भाषाएं केवल एक पैरामीटर सूची को शून्य या अधिक मापदंडों के साथ अनुमति देती हैं, स्काला शून्य या अधिक मापदंडों के साथ शून्य या अधिक पैरामीटर सूची की अनुमति देता है। तो, def foo()एक खाली पैरामीटर सूची के def fooसाथ एक विधि है , और कोई पैरामीटर सूची के साथ एक विधि है और दोनों अलग-अलग चीजें हैं ! सामान्य तौर पर, बिना किसी पैरामीटर सूची वाली विधि को बिना तर्क सूची के साथ बुलाया जाना चाहिए और खाली पैरामीटर सूची के साथ एक विधि को रिक्त तर्क सूची के साथ बुलाया जाना चाहिए। खाली तर्क के साथ कोई पैरामीटर सूची के साथ एक विधि को कॉल करना वास्तव में ...
डब्ल्यू पर Jörg W Mittag

19
... जिस applyविधि को खाली तर्क सूची के साथ विधि कॉल द्वारा लौटाया जाता है, उसे कॉल करने के रूप में व्याख्या की जाती है , जबकि तर्क सूची के बिना रिक्त पैरामीटर सूची के साथ एक विधि को कॉल करना संदर्भ के आधार पर एक अलग तर्क विधि के साथ विधि को कॉल करने के रूप में व्याख्या की जा सकती है, method-आंशिक रूप से लागू विधि (यानी "विधि संदर्भ") में विस्तार, या यह बिल्कुल संकलन नहीं हो सकता है। इसके अलावा, स्काला यूनिफ़ॉर्म एक्सेस सिद्धांत का अनुसरण करता है, न कि (वाक्यगत रूप से) एक तर्क सूची के बिना किसी विधि को कॉल करने और किसी फ़ील्ड को संदर्भित करने के बीच अंतर करना।
डब्ल्यू पर Jörg W Mittag

3
यहां तक ​​कि जब मैं आवश्यक "समारोह" की अनुपस्थिति के लिए रूबी की सराहना करने के लिए आता हूं - पैरेंस, ब्रेसिज़, स्पष्ट प्रकार - मैं बता सकता हूं कि विधि-कोष्ठक तेजी से पढ़ता है ; लेकिन एक बार परिचित मुहावरेदार रूबी काफी पठनीय और निश्चित रूप से लिखने में तेज है।
राडारबॉब

19

यह वास्तव में वाक्यविन्यास विकल्पों का एक बहुत ही सूक्ष्म प्रवाह है। मैं कार्यात्मक भाषाओं से बात करूँगा, जो टाइप किए गए लैम्ब्डा कैलकुलस पर आधारित हैं।

उक्त भाषाओं में, प्रत्येक फ़ंक्शन का एक तर्क होता है । जिसे हम अक्सर "कई तर्क" के रूप में समझते हैं, वह वास्तव में उत्पाद प्रकार का एक ही पैरामीटर है। उदाहरण के लिए, दो पूर्णांक की तुलना करने वाला फ़ंक्शन:

leq : int * int -> bool
leq (a, b) = a <= b

पूर्णांकों की एक जोड़ी लेता है। कोष्ठक फ़ंक्शन मापदंडों को निरूपित नहीं करते हैं ; इनका उपयोग तर्क को मिलाने के लिए किया जाता है । आपको यह समझाने के लिए कि यह वास्तव में एक तर्क है, हम जोड़ी को फिर से बनाने के लिए पैटर्न के बजाय प्रोजेक्टिव फ़ंक्शन का उपयोग कर सकते हैं:

leq some_pair = some_pair.1 <= some_pair.2

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

उस फ़ंक्शन के बारे में क्या जो ओस्टेंसिक रूप से कोई तर्क नहीं है? ऐसा फ़ंक्शन वास्तव में डोमेन है Unit। का एकल सदस्य Unitआमतौर पर लिखा जाता है (), इसीलिए कोष्ठक दिखाई देते हैं।

say_hi : Unit -> string
say_hi a = "Hi buddy!"

इस फ़ंक्शन को कॉल करने के लिए, हमें इसे प्रकार के मूल्य पर लागू Unitकरना होगा, जो होना चाहिए (), इसलिए हम लिखना समाप्त कर देते हैं say_hi ()

तो, वहाँ वास्तव में एक तर्क सूची के रूप में ऐसी कोई बात नहीं है!


3
और यही कारण है कि खाली कोष्ठक ()चम्मच माइनस के सदृश होते हैं।
माइंडविन

3
एक leqफ़ंक्शन को परिभाषित करना जो <इसके बजाय उपयोग करता <=है काफी भ्रामक है!
19

5
इस उत्तर को समझना आसान हो सकता है अगर यह "उत्पाद प्रकार" जैसे वाक्यांशों के अलावा "टपल" शब्द का उपयोग करता है।
केविन

अधिकांश औपचारिकताएं int ^ (int x, int y) को I ^ 2 से I तक एक फ़ंक्शन के रूप में मानेंगी। लैम्बडा कैलकुलस अलग है, यह इस पद्धति का उपयोग अन्य औपचारिकताओं में उच्च मिलान करने के लिए नहीं करता है। इसके बजाय लैम्ब्डा कैलकुलस करी का उपयोग करता है। तुलना x -> (y -> (x <= y)) होगी। (x -> (y -> (x <= y)) २ का मूल्यांकन होगा (y-> २ <= y) और (x -> (y -> (x <= y)) २ ३ का मूल्यांकन होगा ( y-> 2 <= y) 3 जो बदले में 2 <= 3 का मूल्यांकन करता है।
तैमूर

1
@PeriataBreatta मैं ()इकाई का प्रतिनिधित्व करने के लिए उपयोग करने के इतिहास से परिचित नहीं हूं । मुझे आश्चर्य नहीं होगा अगर कारण का कम से कम हिस्सा "पैरामीटर रहित फ़ंक्शन" जैसा दिखना था। हालाँकि, सिंटैक्स के लिए एक और संभावित स्पष्टीकरण है। प्रकारों के बीजगणित में, Unitवास्तव में उत्पाद प्रकारों के लिए पहचान है। एक द्विआधारी उत्पाद के रूप में लिखा है (a,b), हम के रूप में एक unary उत्पाद लिख सकते हैं (a), इसलिए एक तार्किक विस्तार के रूप में बस nullary उत्पाद लिखना होगा ()
बाग़ 13

14

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

जावा में चुनाव किया गया था कि एक पहचानकर्ता द्वारा पीछा किया गया () या (...) का अर्थ है एक विधि कॉल जिसके बिना एक पहचानकर्ता सदस्य चर को संदर्भित करता है। यह पठनीयता में सुधार कर सकता है, क्योंकि आपको इसमें कोई संदेह नहीं है कि आप किसी विधि या सदस्य चर के साथ काम कर रहे हैं। वास्तव में, एक ही नाम का उपयोग विधि और सदस्य चर दोनों के लिए किया जा सकता है, दोनों अपने संबंधित वाक्यविन्यास के साथ सुलभ होंगे।


4
+1 जब तक कोड को मनुष्यों द्वारा पढ़ा जाना आवश्यक है, पठनीयता राजा है।
ट्यूलेंस कोरडोवा

1
@ TulainsCórdova मुझे यकीन नहीं है कि पर्ल आपसे सहमत हैं।
रैचेट

@ रैचेत: पर्ल शायद नहीं लेकिन Perl Best Practicesकरता है
स्लीबेटमैन

1
@Racheet पर्ल बहुत पठनीय है अगर यह पठनीय लिखा जाए। यह बहुत ज्यादा हर गैर-गूढ़ भाषा के लिए समान है। लघु, संक्षिप्त पर्ल पर्ल प्रोग्रामर्स के लिए बहुत पठनीय है, ठीक उसी तरह जैसे स्काला या हास्केल कोड उन भाषाओं में अनुभवी लोगों के लिए पठनीय है। मैं आपको बहुत ही जटिल तरीके से जर्मन बोल सकता हूं जो व्याकरणिक रूप से पूरी तरह से सही है, लेकिन फिर भी आप एक शब्द भी नहीं समझ पाएंगे, भले ही आप जर्मन में कुशल हों। यह जर्मन की गलती भी नहीं है। ;)
सिमबेक

जावा में यह एक विधि "पहचान" नहीं करता है। इसे कहते हैं। Object::toStringएक विधि की पहचान करता है।
njzk2

10

सिंटैक्स शब्दार्थ का अनुसरण करता है, तो आइए शब्दार्थ से शुरू करें:

किसी फ़ंक्शन या विधि का उपयोग करने के तरीके क्या हैं?

वास्तव में, कई तरीके हैं:

  • एक फ़ंक्शन को तर्कों के साथ या बिना बुलाया जा सकता है
  • एक फ़ंक्शन को एक मूल्य के रूप में माना जा सकता है
  • एक फ़ंक्शन आंशिक रूप से लागू किया जा सकता है (कम से कम एक कम तर्क लेने और पारित किए गए तर्कों पर बंद होने का निर्माण करना)

अलग-अलग उपयोगों के लिए एक समान वाक्य-विन्यास होना अस्पष्ट भाषा बनाने का सबसे अच्छा तरीका है या बहुत कम से कम एक भ्रमित करने वाला (और हमारे पास पर्याप्त है)।

C और C जैसी भाषाओं में:

  • किसी फ़ंक्शन को कॉलिंग को कोष्ठक का उपयोग करके तर्कों को संलग्न करने के लिए किया जाता है (जैसा कि कोई नहीं हो सकता है) func()
  • किसी फ़ंक्शन को मान के रूप में मानकर उसके नाम का उपयोग करके किया जा सकता है &func(C एक फ़ंक्शन पॉइंटर बनाने वाला)
  • कुछ भाषाओं में, आपके पास आंशिक रूप से आवेदन करने के लिए शॉर्ट-हैंड सिंटैक्स हैं; जावा someVariable::someMethodउदाहरण के लिए अनुमति देता है (विधि रिसीवर तक सीमित है, लेकिन अभी भी उपयोगी है)

ध्यान दें कि प्रत्येक उपयोग में एक अलग वाक्यविन्यास होता है, जिससे आप उन्हें आसानी से अलग बता सकते हैं।


2
ठीक है, "आसानी से" उन लोगों में से एक है "यह स्पष्ट है केवल अगर इसकी पहले से ही समझी गई" स्थितियां। एक शुरुआत पूरी तरह से ध्यान देने योग्य होगी कि यह बिना किसी स्पष्टीकरण के किसी भी तरह से स्पष्ट नहीं है कि कुछ विराम चिह्न का अर्थ क्यों है।
एरिक लिपर्ट

2
@EricLippert: वास्तव में, आसानी से सहज ज्ञान युक्त मतलब नहीं है। हालांकि इस मामले में मैं कहना चाहूंगा कि गणित में फंक्शन "इनवोकेशन" के लिए कोष्ठक का भी उपयोग किया जाता है। यह कहा जा रहा है, मुझे कई भाषाओं में शुरुआती मिल गए हैं जो सामान्य रूप से वाक्य रचना की तुलना में अवधारणाओं / शब्दार्थों से अधिक संघर्ष कर रहे हैं।
मथिउ एम।

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

@PeriataBreatta: अच्छा बिंदु, निश्चित।
मैथ्यू एम।

8

किसी साइड इफ़ेक्ट वाली भाषा में, यह IMO वास्तव में एक चर के सिद्धांत (थ्योरी साइड इफ़ेक्ट फ़्री) में अंतर करने में सहायक है

variable

और एक समारोह को बुला रहा है, जो साइड इफेक्ट हो सकता है

launch_nukes()

OTOH, यदि कोई साइड इफेक्ट नहीं हैं (टाइप सिस्टम में एन्कोडेड के अलावा) तो एक चर को पढ़ने और बिना किसी तर्क के फ़ंक्शन को कॉल करने के बीच अंतर करने का कोई मतलब नहीं है।


1
ध्यान दें कि ओपी ने उस मामले को प्रस्तुत किया जहां एक ऑब्जेक्ट एकमात्र तर्क है और फ़ंक्शन नाम से पहले प्रस्तुत किया जाता है (जो फ़ंक्शन नाम के लिए एक गुंजाइश भी प्रदान करता है)। noun.verbवाक्यविन्यास अर्थ के रूप में स्पष्ट noun.verb()और थोड़ा कम बरबाद हो सकता है। इसी तरह, एक member_बाएं संदर्भ को लौटाने वाला एक फ़ंक्शन एक विशिष्ट सेटर फ़ंक्शन की तुलना में एक अनुकूल वाक्यविन्यास पेश कर सकता है: obj.member_ = new_valueबनाम obj.set_member(new_value)( _पोस्टफ़िक्स एक संकेत है जो "छिपा हुआ" कार्यों के लिए _ उपसर्गों की याद दिलाता है "उजागर " है)।
पॉल ए। क्लेटन

1
@ PaulA.Clayton मैं यह नहीं देखता कि यह मेरे उत्तर द्वारा कैसे कवर नहीं किया जाता है: यदि noun.verbफ़ंक्शन फ़ंक्शन आह्वान करता है, तो आप इसे मात्र सदस्य पहुंच से कैसे अलग करते हैं?
डैनियल जर्स

1
पढ़ने के चर के सैद्धांतिक रूप से दुष्प्रभावों से मुक्त होने के संबंध में, मैं सिर्फ यह कहना चाहता हूं: हमेशा झूठे दोस्तों से सावधान रहें
जस्टिन टाइम

8

किसी भी अन्य उत्तर ने इस सवाल से निपटने का प्रयास नहीं किया है: किसी भाषा के डिजाइन में कितनी अतिरेक होनी चाहिए? क्योंकि भले ही आप एक भाषा डिज़ाइन कर सकते हैं ताकि x = sqrt yx को y के वर्गमूल में सेट किया जा सके, इसका मतलब यह नहीं है कि आपको जरूरी होना चाहिए।

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

अतिरेक पठनीयता में भी मदद करता है, क्योंकि अधिक सुराग हैं। अतिरेक के बिना अंग्रेजी पढ़ना बहुत कठिन होगा, और प्रोग्रामिंग भाषाओं का भी यही हाल है।


एक मायने में मैं सहमत हूं: प्रोग्रामिंग भाषाओं में "सुरक्षा जाल" तंत्र होना चाहिए। लेकिन मैं असहमत हूं कि वाक्यविन्यास में "थोड़ी सी अतिरेक" इसके बारे में जाने का एक अच्छा तरीका है - यह बॉयलरप्लेट है , और यह ज्यादातर ऐसा करता है जो शोर को पेश करता है, जो त्रुटियों को स्पॉट करने के लिए कठिन बनाता है, और वाक्यविन्यास त्रुटियों के लिए संभावनाएं खोलता है जो इससे विचलित होते हैं असली कीड़े। इस तरह की क्रियाशीलता जो एड्स की पठनीयता को वाक्य रचना के साथ कम, नामकरण सम्मेलनों के साथ अधिक होती है । और एक सुरक्षा जाल अब तक सबसे अधिक कुशलता से एक मजबूत प्रकार की प्रणाली के रूप में लागू किया गया है , जिसमें अधिकांश यादृच्छिक परिवर्तन कार्यक्रम को बीमार टाइप करेंगे।
२.५५

@leftaroundabout: मुझे हैमिंग दूरी के संदर्भ में भाषा डिजाइन के फैसले के बारे में सोचना पसंद है। यदि दो निर्माणों के अलग-अलग अर्थ होते हैं, तो कम से कम दो तरीकों से भिन्न होने के लिए यह अक्सर सहायक होता है, और एक ऐसा रूप होता है जो केवल एक ही तरीके से अलग होता है जो एक कंपाइलर स्क्वॉक उत्पन्न करता है। भाषा डिजाइनर आम तौर पर यह सुनिश्चित करने के लिए ज़िम्मेदार नहीं हो सकता है कि पहचानकर्ता आसानी से भेद कर सकते हैं, लेकिन अगर उदाहरण के लिए असाइनमेंट की आवश्यकता होती है :=और तुलना की जाती है ==, =केवल संकलन-समय आरंभीकरण के लिए उपयोग करने योग्य होने के बाद, तो टाइपोस की तुलना असाइनमेंट में बदलने की संभावना बहुत कम हो जाएगी।
सुपरकैट

@leftaroundabout: LIkewise, अगर मैं एक भाषा डिज़ाइन कर रहा था, तो मुझे ()एक शून्य-तर्क फ़ंक्शन के आह्वान की आवश्यकता होगी , लेकिन एक फ़ंक्शन का "पता लेने के लिए" एक टोकन की भी आवश्यकता होगी। पूर्व की कार्रवाई बहुत अधिक सामान्य है, इसलिए कम सामान्य मामले में एक टोकन को सहेजना यह सब उपयोगी नहीं है।
सुपरकैट

@ सुपरकैट: ठीक है, फिर से मुझे लगता है कि यह समस्या को गलत स्तर पर हल कर रहा है। असाइनमेंट और तुलना वैचारिक रूप से अलग-अलग ऑपरेशन हैं, इसलिए क्रमशः फ़ंक्शन मूल्यांकन और फ़ंक्शन-एड्रेस ले रहे हैं। इसलिए उनके पास स्पष्ट रूप से अलग प्रकार होना चाहिए, फिर यह वास्तव में कोई फर्क नहीं पड़ता है यदि ऑपरेटरों के पास कम हैमिंगिंग दूरी है, क्योंकि कोई भी टाइपो एक संकलन-समय प्रकार की त्रुटि होगी।
१६:०६

@leftaroundabout: यदि कोई असाइनमेंट बूलियन-टाइप वैरिएबल में बनाया जा रहा है, या यदि फ़ंक्शन का रिटर्न प्रकार ही फ़ंक्शन के लिए एक पॉइंटर है (या - कुछ भाषाओं में - एक वास्तविक फ़ंक्शन), असाइनमेंट के साथ तुलना की जगह। या एक फ़ंक्शन संदर्भ के साथ एक समारोह आह्वान, एक ऐसा कार्यक्रम पेश कर सकता है जो वाक्यविन्यास रूप से मान्य है, लेकिन मूल संस्करण से पूरी तरह से अलग अर्थ है। टाइप चेकिंग में सामान्य तौर पर कुछ ऐसी त्रुटियां देखने को मिलेंगी, लेकिन वाक्यविन्यास को अलग बनाना एक बेहतर दृष्टिकोण की तरह लगता है।
सुपरकैट

5

ज्यादातर मामलों में, ये भाषा के व्याकरण के वाक्यविन्यास विकल्प हैं। यह विभिन्न व्यक्तिगत निर्माण के लिए व्याकरण के लिए उपयोगी होता है (अपेक्षाकृत) जब सभी को एक साथ लिया जाता है। (यदि कुछ सी ++ घोषणाओं की तरह अस्पष्टताएं हैं, तो समाधान के लिए विशिष्ट नियम होने चाहिए।) संकलक में अनुमान लगाने के लिए अक्षांश नहीं है; भाषा विनिर्देश का पालन करना आवश्यक है।


विजुअल बेसिक, विभिन्न रूपों में, उन प्रक्रियाओं के बीच अंतर करता है जो एक मूल्य, और फ़ंक्शन वापस नहीं करते हैं।

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

यह एक अपेक्षाकृत अनावश्यक अंतर है जो दो रूपों के बीच मैनुअल रिफैक्टिंग बनाता है जो कि अधिक दर्दनाक है।

(दूसरी ओर विजुअल बेसिक एक ही कोष्ठक का उपयोग करता ()समारोह कॉल के लिए के रूप में सरणी संदर्भ के लिए है, तो सरणी संदर्भ फ़ंक्शन को कॉल की तरह लग रहे। और यह एक समारोह कॉल में एक सरणी के मैनुअल रिफैक्टरिंग को आसान बनाता है! तो, हम विचार कर सकता है अन्य भाषाओं का उपयोग []के सरणी संदर्भों के लिए, लेकिन मैं ...


सी और सी ++ भाषाओं में चर की सामग्री उनके नाम का उपयोग करके स्वचालित रूप से एक्सेस की जाती है, और यदि आप इसकी सामग्री के बजाय चर को संदर्भित करना चाहते हैं, तो आप अपर &ऑपरेटर को लागू करते हैं ।

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

यह पूरी तरह से प्रशंसनीय है (जैसा कि इसके लिए अन्य वाक्यात्मक विकल्प हैं)।


2
बेशक, जबकि विजुअल बेसिक में ब्रैकेट्स की कमी की कमी को देखते हुए कॉल्स अपने फंक्शन कॉल्स की तुलना में एक अनावश्यक अंतर है, उनके लिए आवश्यक ब्रैकेट्स जोड़ना बयानों के बीच एक अनावश्यक अंतर होगा , जिनमें से कई बेसिक-व्युत्पन्न भाषा में प्रभाव होते हैं जो बहुत होते हैं प्रक्रियाओं की याद दिलाता है। जब से मैंने MS BASIC संस्करण में कोई काम किया है, तब तक यह भी एक समय है, लेकिन क्या यह अभी भी वाक्यविन्यास की अनुमति नहीं देता है call <procedure name> (<arguments>)? यकीन है कि जब मैं एक और जीवनकाल में QuickBASIC प्रोग्रामिंग किया था, तो वापस प्रक्रियाओं का उपयोग करने का एक वैध तरीका था ...
Periata Breatta

1
@PeriataBreatta: VB अभी भी "कॉल" वाक्यविन्यास की अनुमति देता है, और कभी-कभी उन मामलों में भी इसकी आवश्यकता होती है जहां पर कॉल की जाने वाली चीज़ एक अभिव्यक्ति है [जैसे कोई कह सकता है "कॉल इफ़ (ifCondition, Delegate1, Delegate2) (तर्क)", लेकिन प्रत्यक्ष "यदि" ऑपरेटर के परिणाम का आह्वान स्टैंडअलोन स्टेटमेंट के रूप में मान्य नहीं होगा]।
सुपरकैट

@PeriataBreatta मुझे VB6 की कोई ब्रैकेट प्रक्रिया कॉल पसंद नहीं आई क्योंकि इसने डीएसएल-जैसे कोड को अच्छा बनाया।
मार्क हर्ड

@supercat LinqPad में, यह आश्चर्यजनक है कि मुझे कितनी बार Callएक ऐसी विधि के लिए उपयोग करने की आवश्यकता है जहां मुझे लगभग "सामान्य" उत्पादन कोड की आवश्यकता नहीं है।
मार्क हर्ड

5

संगति और पठनीयता।

अगर मुझे पता है कि आप फ़ंक्शन Xको इस तरह कहते हैं : X(arg1, arg2, ...)तो मुझे उम्मीद है कि यह बिना किसी तर्क के उसी तरह काम करेगा X():।

अब उसी समय मैं सीखता हूं कि आप चर को कुछ प्रतीक के रूप में परिभाषित कर सकते हैं, और इसे इस तरह उपयोग कर सकते हैं:

a = 5
b = a
...

अब जब मुझे यह पता चलेगा तो मैं क्या सोचूंगा?

c = X

तुम्हारा अंदाज़ा मेरी तरह सटीक है। सामान्य परिस्थितियों में, Xएक चर है। लेकिन अगर हम आपका रास्ता अपनाएँ, तो यह भी एक समारोह हो सकता है! क्या मुझे याद है कि कौन से प्रतीक किस समूह (चर / कार्यों) के लिए मैप करते हैं?

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

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

साइड-नोट 2: स्वीकृत उत्तर हमें वाक्यविन्यास दिखाता है object.functionname:। सबसे पहले, यह प्रथम श्रेणी के कार्यों वाली भाषाओं के लिए सार्वभौमिक नहीं है। दूसरे, एक प्रोग्रामर मैं एक अतिरिक्त जानकारी के रूप में इस का इलाज के रूप में: functionnameएक के अंतर्गत आता है object। चाहे objectकोई वस्तु हो, एक वर्ग या एक नाम स्थान इससे बहुत अधिक मायने नहीं रखता है, लेकिन यह मुझे बताता है कि यह कहीं का है । इसका मतलब है कि आपको object.प्रत्येक वैश्विक फ़ंक्शन के लिए कृत्रिम सिंटैक्स जोड़ना होगा या objectसभी वैश्विक फ़ंक्शन रखने के लिए कुछ बनाना होगा ।

और किसी भी तरह से, आप फ़ंक्शन और चर के लिए अलग नामस्थान रखने की क्षमता खो देते हैं।


हाँ। संगति एक अच्छा पर्याप्त कारण है, पूर्ण विराम (ऐसा नहीं है कि आपके अन्य बिंदु वैध नहीं हैं - वे हैं)।
मैथ्यू पढ़ें

4

अन्य उत्तरों में जोड़ने के लिए, इस C का उदाहरण लें:

void *func_factory(void)
{
        return 0;
}

void *(*ff)(void);

void example()
{
        ff = func_factory;
        ff = func_factory();
}

यदि आह्वान संचालक वैकल्पिक था, तो फ़ंक्शन असाइनमेंट और फ़ंक्शन कॉल के बीच अंतर करने का कोई तरीका नहीं होगा।

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


3
जावास्क्रिप्ट में एक प्रकार की प्रणाली की कमी नहीं है। इसमें प्रकार की घोषणाओं का अभाव है । लेकिन यह पूरी तरह से विभिन्न प्रकार के मूल्य के बीच के अंतर से अवगत है।
पेरियाटा ब्रीटा

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

उदाहरण के लिए, यह कार्य क्या करता है? function cross(a, b) { return a + b; }
मार्क के कोवन

@MarkKCowan यह इस प्रकार है: ecma-international.org/ecma-262/6.0/…
curiousdannii
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.