असाइनमेंट ऑपरेटर को एक मान वापस करने से क्या लाभ होगा?


27

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

जिन चीजों को मैं बदलना चाहता था उनमें से एक था असाइनमेंट ऑपरेटर को असाइनमेंट कमांड में बदलना, लौटे मूल्य का उपयोग करने की क्षमता को हटाना।

x=1;          /* Assignment. */
if (x==1) {}  /* Comparison. */
x==1;         /* Error or warning, I've not decided yet. */
if (x=1) {}   /* Error. */

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

या यह है? असाइनमेंट ऑपरेटर के वापसी मूल्य के कोई व्यावहारिक उपयोग हैं जो तुच्छ रूप से फिर से लिखे नहीं जा सकते हैं? (किसी भी भाषा के लिए ऐसी अवधारणा है।)


12
JS और PHP में एक बड़ा "इंस्टॉल बेस" नहीं है?
मैहर

47
@ श्री मुझे व्यंग्य पर संदेह है।
एंडी हंट

12
एकमात्र उपयोगी मामला जो मुझे याद है वह है while((x = getValue()) != null) {}। रिप्लेसमेंट बदसूरत होगा क्योंकि आपको असाइनमेंट का उपयोग करने breakया दोहराने की आवश्यकता होगी x = getValue
कोडइन्चोज

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

4
मैं आपको सुझाव दूंगा कि यदि आपका इरादा किसी मौजूदा भाषा को बढ़ाने का है और आप इसे व्यापक रूप से अपनाने का इरादा रखते हैं तो मौजूदा भाषा के साथ 100% पीछे की संगतता अच्छी है। टाइपस्क्रिप्ट को एक उदाहरण के रूप में देखें। यदि आपका इरादा किसी मौजूदा भाषा को बेहतर विकल्प प्रदान करना है, तो आपको बहुत कठिन समस्या है। एक नई भाषा को मौजूदा यथार्थवादी समस्या को हल करने की लागत का भुगतान करने के लिए मौजूदा भाषा की तुलना में बहुत बेहतर हल करना है । भाषा सीखना एक निवेश है और इसे चुकाना होगा।
एरिक लिपर्ट

जवाबों:


25

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

मौजूदा भाषाओं पर एक नज़र जो ऐसा करते हैं वह सार्थक हो सकती है।

  • जावा और सी # असाइनमेंट को एक अभिव्यक्ति बनाए रखते हैं लेकिन आपके द्वारा उल्लिखित नुकसान को हटाकर बूलियंस का मूल्यांकन करने के लिए शर्तों की आवश्यकता होती है। यह ज्यादातर है, हालांकि लोग कभी कभी शिकायत इस अनुमति नहीं देता है की स्थिति की तरह है कि अच्छी तरह से काम करने लगता है if (x)के स्थान पर if (x != null)या if (x != 0)के प्रकार पर निर्भर x
  • पायथन एक अभिव्यक्ति के बजाय एक उचित बयान असाइनमेंट करता है। इसे कभी-कभार बदलने के प्रस्ताव अजगर-विचारों की मेलिंग सूची तक पहुँचते हैं, लेकिन मेरी व्यक्तिपरक धारणा यह है कि यह अधिक दुर्लभ रूप से होता है और हर बार कम शोर उत्पन्न करता है, जैसे कि अन्य "गायब" सुविधाओं जैसे कि डू-लूप, स्विच स्टेटमेंट, मल्टी-लाइन लैम्ब्डा, आदि।

हालाँकि, पायथन एक विशेष मामले की अनुमति देता है, एक साथ कई नामों को निर्दिष्ट करता है a = b = c:। इसे एक कथन के बराबर माना जाता है b = c; a = b, और यह कभी-कभी उपयोग किया जाता है, इसलिए यह आपकी भाषा में भी जोड़ने के लायक हो सकता है (लेकिन मुझे यह पसीना नहीं आएगा, क्योंकि यह जोड़ पीछे की ओर संगत होना चाहिए)।


5
+1 को लाने के लिए a = b = cजो अन्य उत्तर वास्तव में नहीं लाते हैं।
सिंह

6
एक तीसरा संकल्प असाइनमेंट के लिए एक अलग प्रतीक का उपयोग करना है। :=असाइनमेंट के लिए पास्कल का उपयोग करता है।
ब्रायन

5
@ ब्रायन: दरअसल, जैसा कि सी #। =असाइनमेंट है, ==तुलना है।
मार्जन वेनमा

3
C # में, ऐसा कुछ C4706 चेतावनी ( ) if (a = true)फेंक देगा । सी के साथ GCC भी इसी तरह एक फेंक देंगे । उन चेतावनियों को कोष्ठक के एक अतिरिक्त समूह के साथ खामोश किया जा सकता है, लेकिन वे वहाँ हैं जिससे स्पष्ट रूप से संकेत मिलता है कि असाइनमेंट जानबूझकर था। The test value in a conditional expression was the result of an assignment.warning: suggest parentheses around assignment used as truth value [-Wparentheses]
बॉब

2
@delnan कुछ हद तक सामान्य टिप्पणी है, लेकिन इसे "मलिन बस्तियों का मूल्यांकन करने के लिए शर्तों की आवश्यकता से आपके द्वारा उल्लिखित नुकसान को दूर करना" द्वारा स्पार्क किया गया था - एक बूलियन का मूल्यांकन a = true करता है और इसलिए यह कोई त्रुटि नहीं है, लेकिन यह C # में संबंधित चेतावनी भी उठाता है।
बॉब

11

असाइनमेंट ऑपरेटर के वापसी मूल्य के कोई व्यावहारिक उपयोग हैं जो तुच्छ रूप से फिर से लिखे नहीं जा सकते हैं?

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

आम उपयोग आमतौर पर अभिव्यक्ति को कॉम्पैक्ट बनाने के लिए होते हैं:

x = y = z;

के सी # में शब्दार्थ है "z को y के प्रकार में कनवर्ट करें, परिवर्तित मान को y में असाइन करें, परिवर्तित मान अभिव्यक्ति का मूल्य है, इसे x के प्रकार में परिवर्तित करें, x पर असाइन करें"।

लेकिन हम पहले से ही एक बयान के संदर्भ में अपूर्ण दुष्प्रभावों के दायरे में हैं, इसलिए उस पर वास्तव में बहुत कम लाभ है

y = z;
x = y;

इसी तरह से

M(x = 123);

के लिए एक आशुलिपि जा रहा है

x = 123;
M(x);

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

मैं एक ऐसी भाषा विकसित कर रहा हूं जिसे मैं जावास्क्रिप्ट और पीएचपी दोनों को बदलने का इरादा रखता हूं।

यदि आप वास्तव में बोल्ड होना चाहते हैं और इस बात पर जोर देना चाहते हैं कि असाइनमेंट एक स्टेटमेंट है और समानता नहीं है, तो मेरी सलाह है: इसे स्पष्ट रूप से असाइनमेंट स्टेटमेंट बनाएं

let x be 1;

एक लाल। या

x <-- 1;

या इससे भी बेहतर:

1 --> x;

या अभी भी बेहतर है

1 → x;

वहाँ बिल्कुल कोई रास्ता नहीं है कि उन में से किसी के साथ भ्रमित होने जा रहे हैं x == 1


1
क्या प्रोग्रामिंग भाषाओं में गैर-एएससीआईआई यूनिकोड प्रतीकों के लिए दुनिया तैयार है?
बिल्वपत्र

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

2
@billpg: क्या दुनिया तैयार है ? मुझे नहीं पता - यूनिकोड के आविष्कार से दशकों पहले 1964 में दुनिया एपीएल के लिए तैयार थी? यहां एपीएल में एक कार्यक्रम है जो पहले 40 में से छह नंबरों का एक यादृच्छिक क्रमांकन चुनता है: x[⍋x←6?40] एपीएल को अपने विशेष कीबोर्ड की आवश्यकता थी, लेकिन यह एक बहुत ही सफल भाषा थी।
एरिक लिपर्ट

@billpg: मैकिंटोश प्रोग्रामर की वर्कशॉप ने रेगेक्स टैग या स्टेडर के पुनर्निर्देशन जैसी चीजों के लिए गैर-एएससीआईआई प्रतीकों का उपयोग किया। दूसरी ओर, MPW का यह फायदा था कि Macintosh ने गैर-ASCII वर्ण टाइप करना आसान बना दिया। मुझे कुछ पहेली को स्वीकार करना चाहिए कि क्यों यूएस कीबोर्ड ड्राइवर किसी भी गैर-एएससीआईआई अक्षरों को टाइप करने का कोई सभ्य साधन प्रदान नहीं करता है। न केवल Alt-number प्रविष्टि के लिए वर्ण कोड देखने की आवश्यकता होती है - कई अनुप्रयोगों में यह काम भी नहीं करता है।
सुपरकैट

हम्म, क्यों "सही" को असाइन करना पसंद करेंगे a+b*c --> x? यह मुझे अजीब लगता है।
रुस्लान

9

कई भाषाएं अभिव्यक्ति के बजाय कथन बनाने का मार्ग चुनती हैं, जिसमें पायथन भी शामिल है:

foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg

और गोलंग:

var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies

अन्य भाषाओं में असाइनमेंट नहीं है, बल्कि स्काइन्ड बाइंडिंग, जैसे OCaml:

let foo = 42 in
  if foo = 42 then
    print_string "hi"

हालाँकि, letएक अभिव्यक्ति ही है।

असाइनमेंट की अनुमति देने का लाभ यह है कि हम सशर्त के अंदर किसी फ़ंक्शन के रिटर्न मान की जांच कर सकते हैं, उदाहरण के लिए इस पर्ल स्निपल में:

if (my $result = some_computation()) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}

पर्ल अतिरिक्त रूप से केवल उस सशर्त के लिए घोषणा करता है, जो इसे बहुत उपयोगी बनाता है। यह भी चेतावनी देगा यदि आप एक नया चर घोषित किए बिना एक सशर्त के अंदर असाइन करते हैं - if ($foo = $bar)चेतावनी if (my $foo = $bar)देंगे , नहीं करेंगे।

एक और बयान में असाइनमेंट बनाना आमतौर पर पर्याप्त है, लेकिन स्कूपिंग समस्याएं ला सकता है:

my $result = some_computation()
if ($result) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}
# $result is still visible here - eek!

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

if result, err := some_computation(); err != nil {
  fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)

अन्य भाषाएं सशर्त के अंदर गैर-बूलियन अभिव्यक्तियों को अस्वीकार करने के लिए एक प्रकार की प्रणाली का उपयोग करती हैं:

int foo;
if (foo = bar()) // Java does not like this

बेशक, एक बूलियन को वापस करने वाले फ़ंक्शन का उपयोग करते समय विफल हो जाता है।

अब हमने आकस्मिक कार्य से बचाव के लिए विभिन्न तंत्र देखे हैं:

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

मैंने उन्हें आरोही वरीयता के क्रम में रैंक किया है - अभिव्यक्ति के अंदर असाइनमेंट उपयोगी हो सकते हैं (और स्पष्ट घोषणा सिंटैक्स, और एक अलग नाम तर्क वाक्यविन्यास होने से पायथन की समस्याओं को दरकिनार करना सरल है)। लेकिन उन्हें खारिज करना ठीक है, क्योंकि एक ही प्रभाव के लिए कई अन्य विकल्प हैं।

बग-मुक्त कोड, terse कोड से अधिक महत्वपूर्ण है।


+1 "अभिव्यक्ति के रूप में असाइनमेंट को अस्वीकार करें" के लिए। असाइनमेंट-ए-ए-एक्सप्रेशन के लिए उपयोग के मामले बग और पठनीयता के मुद्दों की क्षमता को सही नहीं ठहराते हैं।
प्रहार

7

आपने कहा "मुझे लगा (मेरे व्यक्तिगत अनुभव से परे थोड़े सा सबूतों के साथ) कि इस समय का अधिकांश हिस्सा घटित हुआ, यह वास्तव में वृद्धि ऑपरेशन होने का इरादा था।"

समस्या क्यों नहीं?

समानता परीक्षण के लिए = और समानता परीक्षण के लिए = के बजाय, असाइनमेंट के लिए = = का उपयोग क्यों नहीं करते हैं और = (या भी ==) समानता के लिए?

का निरीक्षण करें:

if (a=foo(bar)) {}  // obviously equality
if (a := foo(bar)) { do something with a } // obviously assignment

यदि आप प्रोग्रामर को समानता के लिए गलती असाइनमेंट के लिए कठिन बनाना चाहते हैं, तो इसे कठिन बनाएं।

उसी समय, यदि आप वास्तव में समस्या को ठीक करना चाहते हैं, तो आप C crock को हटा देंगे जो दावा किया था कि बूलियन पूर्वनिर्धारित प्रतीकात्मक चीनी नामों के साथ पूर्णांक थे। उन्हें पूरी तरह से एक अलग प्रकार बनाओ। फिर कहने के बजाय

int a = some_value();
if (a) {}

आप प्रोग्रामर को लिखने के लिए मजबूर करते हैं:

int a = some_value();
if (a /= 0) {} // Note that /= means 'not equal'.  This is your Ada lesson for today.

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


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

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

1
@delnan: एक बुद्धिमान व्यक्ति ने एक बार कहा था "इसे जितना संभव हो उतना सरल बनाओ, लेकिन कोई सरल नहीं।" यदि आपका उद्देश्य a = b बनाम a == b त्रुटियों के विशाल बहुमत को समाप्त करना है, तो बूलियनों को सशर्त परीक्षणों के डोमेन को प्रतिबंधित करना और <अन्य> के लिए डिफ़ॉल्ट प्रकार के रूपांतरण नियमों को समाप्त करना -> बूलियन आपको सभी तरह के बारे में बताता है। क्या आप वहां मौजूद हैं। उस बिंदु पर, यदि (a = b) {} केवल वाक्यगत रूप से कानूनी है यदि a और b दोनों बूलियन हैं और a एक कानूनी रूप से वैध है।
जॉन आर। स्ट्रोहम

असाइनमेंट बनाना एक कथन के रूप में कम से कम उतना ही सरल है - यकीनन इससे भी सरल - आपके द्वारा प्रस्तावित बदलाव और कम से कम उतना प्राप्त होता है - यकीनन इससे भी अधिक ( if (a = b)ए, बूलियन ए, बी) के लिए अनुमति नहीं देता है । स्थैतिक टाइपिंग के बिना एक भाषा में, यह बहुत बेहतर त्रुटि संदेश देता है (पार्स समय बनाम रन समय)। इसके अलावा, "a = b बनाम a == b त्रुटियां" को रोकना एकमात्र प्रासंगिक उद्देश्य नहीं हो सकता है। उदाहरण के लिए, मैं कोड if items:का मतलब के लिए भी अनुमति देना चाहूंगा if len(items) != 0, और यह कि मुझे बूलियंस को प्रतिबंधित करने की शर्तों को छोड़ना होगा।

1
@delnan पास्कल एक गैर-मुख्यधारा की भाषा है? लाखों लोगों ने पास्कल (और / या मोडुला, जो पास्कल से प्राप्त होता है) का उपयोग करके प्रोग्रामिंग सीखी। और डेल्फी अभी भी आमतौर पर कई देशों में उपयोग किया जाता है (शायद आप में ऐसा नहीं है)।
jwenting

5

वास्तव में इस सवाल का जवाब देने के लिए, हां इसके कई उपयोग हैं, हालांकि वे थोड़े आला हैं।

जावा में उदाहरण के लिए:

while ((Object ob = x.next()) != null) {
    // This will loop through calling next() until it returns null
    // The value of the returned object is available as ob within the loop
}

एम्बेडेड असाइनमेंट का उपयोग किए बिना विकल्प को obलूप के दायरे से बाहर परिभाषित करने और x.next () कॉल करने वाले दो अलग-अलग कोड स्थानों की आवश्यकता होती है।

यह पहले ही उल्लेख किया गया है कि आप एक चरण में कई चर निर्दिष्ट कर सकते हैं।

x = y = z = 3;

इस तरह की बात सबसे आम उपयोग है, लेकिन रचनात्मक प्रोग्रामर हमेशा अधिक के साथ आएंगे।


क्या लूप की स्थिति से निपटने और obहर लूप के साथ एक नई वस्तु का निर्माण होगा ?
user3932000

@ user3932000 उस मामले में शायद नहीं, आमतौर पर x.next () कुछ पर ध्यान दे रहा है। यह निश्चित रूप से संभव है कि यह हालांकि।
टिम बी

1

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

दूसरे शब्दों में, इसे कानूनी बनाएं:

a=b=c=0;

लेकिन इसे अवैध बनाएं:

if (a=b) ...

2
यह एक बल्कि तदर्थ नियम की तरह लगता है। असाइनमेंट बनाना और a = b = cअधिक ऑर्थोगोनल लगता है, और इसे लागू करने के लिए आसान बनाने के लिए इसका विस्तार करना । ये दो दृष्टिकोण अभिव्यक्ति ( a + (b = c)) में असाइनमेंट के बारे में असहमत हैं , लेकिन आपने उन पर पक्ष नहीं लिया है, इसलिए मुझे लगता है कि वे कोई फर्क नहीं पड़ता।

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

यदि आप मल के लिए निहित रूपांतरण को अस्वीकार करते हैं, तो आपको स्थितियों में असाइनमेंट के बारे में चिंता करने की ज़रूरत नहीं है
शाफ़्ट सनकी

लागू करने में आसान केवल मेरे तर्कों में से एक था। बाकी के बारे में क्या? UI कोण से, मैं उस IMHO असंगत डिजाइन और तदर्थ अपवादों को जोड़ सकता हूं जो आम तौर पर उपयोगकर्ता को नियमों को पूरा करने और आंतरिक करने में बाधा डालते हैं।

@ratchetfreak आप अभी भी वास्तविक बूल
jk

0

इसकी ध्वनियों से, आप काफी सख्त भाषा बनाने के मार्ग पर हैं।

इसे ध्यान में रखते हुए, लोगों को लिखने के लिए मजबूर करना:

a=c;
b=c;

के बजाय:

a=b=c;

लोगों को ऐसा करने से रोकने के लिए एक सुधार लग सकता है:

if (a=b) {

जब वे करने का मतलब:

if (a==b) {

लेकिन अंत में, इस तरह की त्रुटियों का पता लगाना आसान है और इस बारे में चेतावनी देना कि वे कानूनी कोड हैं या नहीं।

हालाँकि, ऐसी स्थितियाँ हैं जहाँ करना:

a=c;
b=c;

इसका मतलब यह नहीं है

if (a==b) {

सच होगा।

यदि c वास्तव में एक फंक्शन c () है तो वह हर बार अलग-अलग परिणामों को वापस ला सकता है। (यह कम्प्यूटेशनल रूप से महंगा भी हो सकता है ...)

इसी तरह अगर c मेमोरी मैप्ड हार्डवेयर का पॉइंटर है, तो

a=*c;
b=*c;

दोनों अलग-अलग होने की संभावना है, और प्रत्येक रीड पर हार्डवेयर पर इलेक्ट्रॉनिक प्रभाव भी हो सकते हैं।

हार्डवेयर के साथ बहुत सारे अन्य क्रमपरिवर्तन हैं, जहाँ आपको इस बात की सटीक जानकारी होनी चाहिए कि मेमोरी एड्रेस क्या हैं, जो कि विशिष्ट समय की कमी के कारण, लिखित और उसके तहत पढ़ा जाता है, जहाँ एक ही पंक्ति में कई कार्य करना त्वरित, सरल और स्पष्ट है, बिना समय जोखिम के अस्थायी चर परिचय


4
a = b = cनहीं के बराबर है a = c; b = c, यह है b = c; a = b। यह साइड इफेक्ट्स के दोहराव से बचा जाता है aऔर bउसी क्रम में संशोधन भी करता रहता है । इसके अलावा, ये सभी हार्डवेयर-संबंधी तर्क बेवकूफ़ हैं: अधिकांश भाषाएं सिस्टम भाषा नहीं हैं और न तो इन समस्याओं को हल करने के लिए डिज़ाइन की गई हैं और न ही इन स्थितियों में उनका उपयोग किया जा रहा है जहां ये समस्याएं होती हैं। यह जावास्क्रिप्ट और / या PHP को विस्थापित करने की कोशिश करने वाली भाषा के लिए दोगुना हो जाता है।

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

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

@delnan: प्रतिद्वंद्विता को एक टेम्प के प्रकार में bपरिवर्तित किया जाता है, और इसे aदूसरे टेम्प के प्रकार में परिवर्तित किया जाता है । जब उन मूल्यों को संग्रहीत किया जाता है तो सापेक्ष समय अनिर्दिष्ट होता है। भाषा-डिज़ाइन के नजरिए से, मुझे यह सोचना उचित होगा कि एक बहु-असाइनमेंट स्टेटमेंट में सभी खामियों का मिलान प्रकार होता है, और संभवतः उनमें से किसी को भी अस्थिर होने की आवश्यकता नहीं होती है।
सुपरकैट

0

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

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

असाइनमेंट की अनुमति देने का एक तरीका, या बल्कि असाइनमेंट का प्रभाव, if(x=1)C को LISP जैसे letनिर्माण का उपयोग करने के लिए होने वाली दुर्घटनाओं की संभावना को प्रस्तुत किए बिना एक अभिव्यक्ति है , जैसे कि (let ((x 2) (y 3)) (+ x y))आपकी भाषा में मूल्यांकन हो सकता है 5letइस तरह से उपयोग करने के लिए आपकी भाषा में तकनीकी रूप से असाइनमेंट की आवश्यकता नहीं है, यदि आप letएक शाब्दिक गुंजाइश बनाने के रूप में परिभाषित करते हैं । इस तरह परिभाषित किया गया कि, एक letनिर्माण को उसी तरह संकलित किया जा सकता है जैसे तर्कों के साथ एक नेस्टेड क्लोजर फ़ंक्शन का निर्माण और कॉल करना।

दूसरी ओर, यदि आप बस if(x=1)मामले से चिंतित हैं , लेकिन असाइनमेंट को C के रूप में एक अभिव्यक्ति होना चाहते हैं, तो शायद अलग-अलग टोकन चुनना पर्याप्त होगा। असाइनमेंट: x := 1या x <- 1। तुलना: x == 1। सिंटैक्स त्रुटि x = 1:।


1
letतकनीकी रूप से एक नए दायरे में एक नए चर को पेश करने की तुलना में असाइनमेंट से अलग है। शुरुआत के लिए, यह letशरीर के बाहर कोड पर कोई प्रभाव नहीं है , और इसलिए सभी कोड (जो चर का उपयोग करना चाहिए) नेस्टिंग, आगे असाइनमेंट-भारी कोड में एक महत्वपूर्ण नकारात्मक पक्ष की आवश्यकता है। यदि किसी को उस मार्ग से नीचे जाना था, set!तो बेहतर लिस्प एनालॉग होगा - पूरी तरह से तुलना के विपरीत, फिर भी घोंसले के शिकार या नए दायरे की आवश्यकता नहीं है।

: ) पुनर्वितरण सभी संलग्न स्कोपों ​​में एक चर "अघोषित" होगा। इस प्रकार, किसी भी मान्य पहचानकर्ता का मूल्य उस नाम की पिछली घोषणा में जो भी सौंपा गया था। ऐसा लगता है कि केवल कुछ लाइनों के लिए उपयोग किए जाने वाले चर के लिए स्कूपिंग ब्लॉक को जोड़ने के लिए, या प्रत्येक अस्थायी चर के लिए नए नाम तैयार करने की तुलना में थोड़ा अच्छा होगा।
सुपरकैट

0

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

वास्तव में। यह कोई नई बात नहीं है, C भाषा के सभी सुरक्षित उपसमूह पहले ही यह निष्कर्ष निकाल चुके हैं।

MISRA-C, CERT-C इत्यादि सभी प्रतिबंध कार्य के अंदर स्थितियां, सिर्फ इसलिए कि यह खतरनाक है।

ऐसा कोई भी मामला मौजूद नहीं है जहां कोड को शर्तों के अंदर असाइन करने पर फिर से लिखा नहीं जा सकता है।


इसके अलावा, ऐसे मानक लेखन कोड के खिलाफ भी चेतावनी देते हैं जो मूल्यांकन के आदेश पर निर्भर करते हैं। एक ही पंक्ति x=y=z;में कई असाइनमेंट एक ऐसा मामला है। यदि एकाधिक असाइनमेंट वाली पंक्ति में साइड इफेक्ट्स होते हैं (कॉलिंग फ़ंक्शंस, वाष्पशील चरों को एक्सेस करना आदि), तो आप यह नहीं जान सकते हैं कि कौन सा साइड इफेक्ट पहले होगा।

ऑपरेंड के मूल्यांकन के बीच कोई अनुक्रम बिंदु नहीं हैं। इसलिए हम यह नहीं जान सकते कि क्या उपप्रकार yका पहले या बाद में मूल्यांकन किया जाता है z: यह सी में अनिर्दिष्ट व्यवहार है। इस प्रकार इस तरह के कोड संभावित रूप से अविश्वसनीय, गैर-पोर्टेबल और गैर-अनुरूपता सी के सुरक्षित उपसमूह हैं।

समाधान कोड के साथ प्रतिस्थापित करने के लिए होता y=z; x=y;। यह एक अनुक्रम बिंदु जोड़ता है और मूल्यांकन के क्रम की गारंटी देता है।


इसलिए सी में होने वाली सभी समस्याओं के आधार पर, कोई भी आधुनिक भाषा शर्तों के अंदर दोनों असाइनमेंट पर प्रतिबंध लगाने के साथ-साथ एक ही पंक्ति में कई असाइनमेंट को अच्छी तरह से करेगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.