प्रत्येक के लिए "इन" के बजाय बृहदान्त्र क्यों है?


9

जावा 5 भाषा गाइड से :

जब आप कोलन देखते हैं (:) इसे "इन" के रूप में पढ़ें।

inपहली बार में उपयोग क्यों नहीं ?

यह मुझे सालों से परेशान कर रहा है। क्योंकि यह बाकी भाषा के साथ असंगत है। उदाहरण के लिए, जावा में देखते हैं implements, extends, superसी ++, स्काला या रूबी में जैसे प्रतीकों के बजाय प्रकार के बीच संबंधों के लिए।

जावा संदर्भ में 5 संदर्भों में उपयोग किया जाता है । जिनमें से तीन सी। से विरासत में मिले हैं और अन्य दो जोशुआ बलोच द्वारा समर्थित थे। कम से कम, "द क्लोज़र कॉन्ट्रोवर्सी" बात के दौरान वह साईस थे । यह तब आता है जब वह प्रत्येक शब्दार्थ के साथ असंगत के रूप में मानचित्रण के लिए एक बृहदान्त्र के उपयोग की आलोचना करता है। जो मुझे अजीब लगता है क्योंकि यह प्रत्येक के लिए अपेक्षित दुर्व्यवहार पैटर्न है। जैसा list_name/category: elementsया laberl/term: meaning

मैंने jcp और jsr के आसपास स्नूप किया है, लेकिन मेलिंग सूची का कोई संकेत नहीं मिला। इस विषय पर कोई चर्चा नहीं मिली जो Google द्वारा पाई गई है। बृहदान्त्र के अर्थ में केवल नए-नए भ्रम for


inअब तक प्रदान किए गए खिलाफ मुख्य तर्क :

  • नए कीवर्ड की आवश्यकता है; तथा
  • पेचीदा हो जाता है।

आइए प्रासंगिक व्याकरण की परिभाषा देखें:

बयान
    : 'for' '(' forControl ') स्टेटमेंट
    | ...
    ;

forControl
    : बढ़ायाफोरकंट्रोल
    | forInit? ';' अभिव्यक्ति? ';' forUpdate?
    ;

enhancedForControl
    : variableModifier * टाइप करें variableDeclaratorId ':' अभिव्यक्ति
    ;

से बदलें :करने के लिए inअतिरिक्त जटिलता नहीं लाते है या नए कीवर्ड की आवश्यकता है।


1
भाषा डिजाइनरों की प्रेरणाओं का पता लगाने का सबसे अच्छा स्रोत अक्सर डिजाइनर खुद होते हैं। उस ने कहा, यह स्पष्ट रूप से एक पुनरावृत्त चीनी से अधिक है; देखें stackoverflow.com/questions/11216994/…
रॉबर्ट हार्वे

जवाबों:


8

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

क्यों? मान लेते हैं कि हमारे पास एक सरल टोकन है जो निम्नलिखित टोकन को समझता है:

FOR = 'for'
LPAREN = '('
RPAREN = ')'
IN = 'in'
IDENT = /\w+/
COLON = ':'
SEMICOLON = ';'

टोकनधारक हमेशा सबसे लंबे टोकन से मेल खाएगा, और पहचानकर्ताओं पर कीवर्ड पसंद करेगा। तो के interestingरूप में lexed किया जाएगा IDENT:interesting, लेकिन के रूप में lexed किया inजाएगा IN, कभी नहीं के रूप में IDENT:interesting। एक कोड स्निपेट की तरह

for(var in expression)

टोकन स्ट्रीम में अनुवादित किया जाएगा

FOR LPAREN IDENT:var IN IDENT:expression RPAREN

अब तक, यह काम करता है। लेकिन किसी भी वेरिएबल inको वेरिएबल के INबजाय कीवर्ड के रूप में रखा जाएगा, जो कोड को तोड़ देगा। लेक्सर टोकन के बीच कोई स्थिति नहीं रखता है, और यह नहीं जान सकता है कि inआमतौर पर एक चर होना चाहिए जब हम एक लूप में होते हैं। साथ ही, निम्न कोड कानूनी होना चाहिए:

for(in in expression)

पहला inएक पहचानकर्ता होगा, दूसरा एक कीवर्ड होगा।

इस समस्या पर दो प्रतिक्रियाएँ हैं:

प्रासंगिक कीवर्ड भ्रमित कर रहे हैं, आइए इसके बजाय कीवर्ड का पुन: उपयोग करें।

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

जब हम भाषा का विस्तार करना चाहते हैं, केवल एकमात्र दृष्टिकोण उन प्रतीकों का उपयोग करना है जो पहले भाषा में कानूनी नहीं थे। विशेष रूप से, ये पहचानकर्ता नहीं हो सकते। फ़ॉरच लूप सिंटैक्स के साथ, जावा ने मौजूदा :कीवर्ड को नए अर्थ के साथ पुन: उपयोग किया । लैम्ब्डा के साथ, जावा ने एक ->कीवर्ड जोड़ा जो पहले किसी भी कानूनी कार्यक्रम में नहीं हो सकता था ( -->अभी भी वैसा ही होगा जैसा '--' '>'कि कानूनी है, और ->पहले जैसा हो सकता है '-', '>', लेकिन उस अनुक्रम को पार्सर द्वारा अस्वीकार कर दिया जाएगा)।

प्रासंगिक कीवर्ड भाषाओं को सरल बनाते हैं, उन्हें लागू करते हैं

लेक्सर्स निर्विवाद रूप से उपयोगी हैं। लेकिन पार्सर से पहले एक लेसर चलाने के बजाय, हम उन्हें पार्सर के साथ मिलकर चला सकते हैं। बॉटम-अप पार्सर हमेशा टोकन प्रकार के सेट को जानते हैं जो किसी भी स्थान पर स्वीकार्य होगा। पार्सर फिर लेक्सर से अनुरोध कर सकता है कि वह वर्तमान स्थिति में इनमें से किसी भी प्रकार से मेल खाए। प्रत्येक लूप के लिए, पार्सर उस स्थिति ·में होगा, जो चर के पाए जाने के बाद (सरलीकृत) व्याकरण द्वारा दर्शाया गया है:

for_loop = for_loop_cstyle | for_each_loop
for_loop_cstyle = 'for' '(' declaration · ';' expression ';' expression ')'
for_each_loop = 'for' '(' declaration · 'in' expression ')'

उस स्थिति में, कानूनी टोकन SEMICOLONया हैं IN, लेकिन नहीं IDENT। एक कीवर्ड inपूरी तरह से अस्पष्ट होगा।

इस विशेष उदाहरण में, टॉप-डाउन पार्सर्स को कोई समस्या नहीं होगी क्योंकि हम उपरोक्त व्याकरण को फिर से लिख सकते हैं

for_loop = 'for' '(' declaration · for_loop_rest ')'
for_loop_rest =  · ';' expression ';' expression
for_loop_rest = · 'in' expression

और निर्णय के लिए आवश्यक सभी टोकन बैकट्रैकिंग के बिना देखे जा सकते हैं।

प्रयोज्यता पर विचार करें

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

for (in in in in())
for (in in : in())

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

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


17

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


2
ऐसा लगता है ... असुविधाजनक। यह भाषा डिजाइनरों को शुरू से ही अधिकांश आवश्यक खोजशब्दों का पूर्वानुमान लगाने के लिए पर्याप्त था। मुझे यकीन नहीं है कि यह आवश्यक है; सभ्य संकलक यह निर्धारित कर सकते हैं कि कोई कीवर्ड इसके संदर्भ में परिवर्तनशील है या नहीं।
रॉबर्ट हार्वे

2
मुझे नहीं लगता कि जावा में C # जैसे प्रासंगिक कीवर्ड हैं। तो, उपयोग inकरने का मतलब नए कीवर्ड को प्रस्तुत करना होगा, इस प्रकार बैकवर्ड कम्पैटिबिलिटी ( System.in, किसी को?) को तोड़ना या पहले से अनजान ब्रांड-न्यू कॉन्सेप्ट (प्रासंगिक कीवर्ड) को पेश करना। सभी के लिए क्या लाभ?
जोर्ग डब्ल्यू मित्तग

2
प्रासंगिक कीवर्ड का क्या नुकसान है?
user2418306

5
@ user2418306 किसी कीवर्ड को जोड़ने से मौजूदा कोड को तोड़ने की जरूरत नहीं है, बशर्ते कि भाषा एक अलग लेक्सर चरण के साथ पार्स न हो। विशेष रूप से, एक "इन" for(variable in expression)किसी भी कानूनी कोड के साथ अस्पष्ट नहीं हो सकता है, भले ही "इन" का उपयोग चर के लिए किया जा सके। हालांकि, कई संकलक टूलचिन में एक अलग लेक्सर चरण काफी सामान्य है। यह कुछ सामान्य पार्सर जनरेटर के साथ जावा को पार्स करने के लिए असंभव या कम से कम अधिक कठिन बना देगा। किसी भाषा की वाक्य रचना को सरल रखना आमतौर पर सभी के लिए अच्छा होता है; हर किसी को सी + + या पर्ल जैसे सिंटैक्टिक मॉन्ट्रोसिटी की आवश्यकता नहीं होती है।
अमोन

1
@RobertHarvey: यह मत भूलो constऔर gotoदोनों जावा में आरक्षित शब्द हैं, लेकिन अभी तक उपयोग नहीं किए गए हैं।
टीएमएन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.