आप किस उपयोगी वैकल्पिक नियंत्रण संरचनाओं को जानते हैं? [बन्द है]


12

इसी तरह का सवाल एसओ पर था।

कभी-कभी जब हम प्रोग्रामिंग करते हैं, तो हम पाते हैं कि कुछ विशेष नियंत्रण संरचना हमारे लिए बहुत उपयोगी होगी, लेकिन हमारी प्रोग्रामिंग भाषा में सीधे उपलब्ध नहीं है।

आपको क्या लगता है कि वैकल्पिक नियंत्रण संरचनाएँ संगणना के आयोजन का एक उपयोगी तरीका क्या है?

यहां लक्ष्य यह है कि संरचना कोड के बारे में सोचने के नए तरीके प्राप्त किए जा सकें, ताकि चहकने और तर्क करने में सुधार हो सके।

आप एक इच्छाशील वाक्य रचना / शब्दार्थ अभी उपलब्ध नहीं बना सकते हैं या किसी मौजूद प्रोग्रामिंग भाषा पर कम ज्ञात नियंत्रण संरचना का हवाला दे सकते हैं।

उत्तर नई प्रोग्रामिंग भाषा या वास्तविक भाषा को बढ़ाने के लिए विचार देना चाहिए।

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

यह अनिवार्य प्रोग्रामिंग के बारे में है।


1
यह प्रश्न "अनिवार्य प्रोग्रामिंग" के बारे में क्यों है?
अनुपलब्ध

@missingfaktor: क्योंकि नियंत्रण संरचनाएं अनिवार्य प्रोग्रामिंग के बारे में हैं। निश्चित रूप से, कुछ समस्याओं को कार्यात्मक दृष्टिकोण या किसी अन्य तरीके से हल किया जा सकता है लेकिन अन्य प्रतिमान विकास के केंद्र पर नियंत्रण संरचनाएं नहीं डालते हैं। लेकिन वैसे भी आप रचनात्मक हो सकते हैं।
मनेरियो

3
खैर, मैं पैटर्न मिलान को गार्ड्स के साथ साझा करने जा रहा था, क्योंकि वे अधिक सामान्य हैं जो केस स्टेटमेंट और इफ-थेंस हैं, लेकिन अगर यह कोई एफपी ज़ोन नहीं है, तो मुझे लगता है कि यह बाकी हिस्सों के लिए सिर्फ अधिक पैटर्न मिलान है!
कोडेक्सअर्केनम

@CodexArcanum: खैर, पैटर्न मैचिंग एक निर्माण है जो बहुत ही जरूरी है। वास्तव में, पैटर्न का मिलान अपने आप में अनिवार्य नियंत्रण संरचनाओं का एक विकल्प है। शर्मीली मत बनो ;-)
Maniero

सभी उत्तरों को देखने से मुझे खुशी होती है कि वास्तविक जीवन में कोई भी प्रस्ताव मौजूद नहीं है (और उम्मीद है कि कभी नहीं)। क्षमा करें :)
सर्ग

जवाबों:


14

ठीक है, यह एक मजेदार सवाल है।

मैं पहले elseऔर दूसरे छोरों के लिए भी यही चाहूंगा कि जब पहली परीक्षा में यह शर्त सही न हो तो :

while (condition) {
    // process
}
else {
    // condition was never true
}

यह स्थिति की अजीब पुन: गणना से बचता है या इसे एक चर में संग्रहीत करता है।


अजगर के पास यह है।
बैरी ब्राउन

अरे! अंत में पायथन का एक विचित्र विकल्प जिससे मैं सहमत हूँ! ;-)
मैकनील

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

4
नहीं है एक अनुरोध जोड़ने के लिए while ... elseनिर्माण रास्ता मेकनेल पीएचपी करने के लिए यह वर्णन करता है। मुझे लगता है कि यह एक महान विचार है, क्योंकि "यहां परिणाम हैं / कोई परिणाम नहीं थे" वेब एप्लिकेशन में एक काफी सामान्य मुहावरा है।
डीन हार्डिंग

1
@SnOrfus: वह कोड का एक ब्लॉक (लूप के ब्लॉक से अलग) चाहता है जो केवल तभी निष्पादित होता है जब तक कि शर्त कभी पूरी नहीं होती है। Do-जबकि एक बार सशर्त की परवाह किए बिना कोड के लूप के ब्लॉक (कुछ अलग ब्लॉक नहीं) को निष्पादित करता है।
लीजियन

10

क्यों नहीं एक में कुछ जवाब मैश?

while (expr) {

    // Executed every iteration, unless first{} is present.
    // May be explicitly called rest{} if you like first{} to come first.

    // Blocks may return results, and consequently be used in expressions.
    return expr;

} first {

    // Executed only on the first iteration.

} pre {

    // Executed before every iteration.

} post {

    // Executed after every iteration.

} catch (oops) {

    // All blocks are implicitly try{}ed if followed by a catch{}.

} finally {

    // Executes after the block completes, regardless of exceptions.

} else {

    // Executed if the loop body or rest{} never executes.

} never {

    // Executes only when a client is present.

} drop (bad, worse), // Explicitly ignore certain exceptions.
  until (expr);      // Here, have a post-body condition, too.

एक अनिवार्य भाषा में एक एक्स्टेंसिबल, सामान्यीकृत प्रवाह-नियंत्रण निर्माण सिंटैक्स बल्कि उपयोगी और मनोरंजक होगा। जब तक वह दिखाई नहीं देता, तब तक लगता है कि मैं सिर्फ लिस्प या कुछ का उपयोग करूंगा।


5
उपयोगी नहीं, भ्रमित। मनोरंजक नहीं, धीमा।
जोश के

2
@ जोश के: हाँ, आप सही कह रहे हैं। क्या, तुमने सोचा था कि मैं असहमत हूँ? यह जवाब हंसी से रखने के लिए अपनी जीभ काट रहा है।
जॉन पूर्डी

यदि यह विडंबना से मतलब था, यह निश्चित रूप से सफल रहा!
जोश के

11
+1 ने मुझे हँसाया। पुनरावृत्तियों के बीच निष्पादित करने के लिए कोड के लिए "बीच" खंड की आवश्यकता है।
बैरी ब्राउन

1
+1, लेकिन इसकी आवश्यकता seventh { ... }भी है।
j_random_hacker

7

कार्यों के रूप में नियंत्रण संरचनाओं।

मैं चाहता हूँ for, if, else, while, आदि काम करता है, नहीं विशेष संरचनाओं किया जाना है।

मैं चाहता हूं return, try/exceptऔर gotoनिरंतरता से व्युत्पन्न हो।

यह निश्चित रूप से एक विशेष नियंत्रण संरचना के साथ करने के लिए कम है और सामान्य रूप से नियंत्रण संरचनाओं को कैसे देखें, नियंत्रण संरचनाओं के मेटा के साथ अधिक करने के लिए।


2
निरंतरता एक भाषा के लिए एक भारी अवधारणा है, और कई भाषाओं से उन्हें छोड़ने के अच्छे कारण हैं।
डेविड थॉर्नले

मैं असहमत नहीं हूं; होने for, if, else, और whileकार्यों के रूप में बनाता है मुझे यह निष्कर्ष निकाल कि उन कार्यों के लिए मानकों lazily क्रम मूल निर्माणों के रूप में ही व्यवहार करने में क्रियान्वित किया जा करने की जरूरत है। आलसी निष्पादन करने की क्षमता अच्छा होगा।
डॉ। विली के अपरेंटिस

1
@ डेविड: क्योंकि वे वहां हैं, इसका मतलब यह नहीं है कि आपको उनका उपयोग करना होगा। नियमित प्रोग्रामर उपयोग कर सकते हैं कि वे क्या कर रहे हैं return, अपवाद, आदि। लेकिन अब जरूरत पड़ने पर विशेषज्ञ प्रोग्रामर के पास टूलबॉक्स में एक शक्तिशाली अतिरिक्त टूल है। इसके अलावा, IMHO भाषाओं को "डंबल डाउन" नहीं किया जाना चाहिए। भाषाओं में सीएस ज्ञान की वृद्धि और विशेषज्ञता का समर्थन करने की क्षमता होनी चाहिए।
डायटबुद्ध

1
@ डाटबुड्डा: (प्रतियोगिता) मैं यह नहीं कह रहा हूं कि निरंतरता खराब है, मैं कह रहा हूं कि वे हैवीवेट हैं, और उन्हें प्रयोग करने योग्य बनाने का भाषा के लिए निहितार्थ है, कुछ अपवाद जैसा है। इसके अलावा, निरंतरता में परिवर्तन होने की संभावना है कि लोग भाषा का उपयोग कैसे करें, फिर से C ++ में अपवाद की तरह। निरंतरता का समर्थन करने वाली भाषा अच्छे और बुरे दोनों तरीकों से भिन्न नहीं होगी।
डेविड थॉर्नले

1
@ Steve314 - longjmp एक निरंतरता नहीं है, हालांकि समानताएं हैं। निरंतरता पूरे राज्य (सभी स्थानीय, ग्लोबल्स और स्टैक) को बचाती है। longjmp एक स्टैक पॉइंटर को बचाता है ताकि यदि आप उस दायरे से दूर रहें जहां setjmp का उपयोग किया गया था तो आपको एक segfault मिलता है क्योंकि फ्रेम अब मौजूद नहीं है। मेरा मानना ​​है कि इसे बचाने वाले चरों में कुछ सीमाएँ भी हैं।
४० पर डायटबुद्ध

6

लिंक किए गए लेख को निश्चित रूप से डोनाल्ड नुथ के एन + 1/2 लूप्स के बारे में सही मिलता है । C / C ++ / Java में व्यक्त:

for (;;) {
  get next element;
  if (at the end) break;
  process the element;
}

यह किसी फ़ाइल से लाइनों या वर्णों को पढ़ने के लिए उपयोगी है, यदि आप EOF तक पहुँच चुके हैं, और फिर इसे संसाधित कर रहे हैं। मैं पैटर्न को देखने के लिए इतना for(;;)..if(..)break;अभ्यस्त हूं कि यह मेरे लिए मुहावरा है। (इससे पहले कि मैं नथुना लेख पढ़ चुका था, किताब लिटरेट प्रोग्रामिंग में पुनर्मुद्रित , यह एक "wtf?" हुआ करता था।)

नथ ने कीवर्ड सुझाए loop/while/repeat:

loop:
  S;
while C:
  T;
repeat

कहाँ Sऔर Tशून्य या अधिक बयानों की एक श्रृंखला के लिए जगह धारक हैं, और Cएक बूलियन स्थिति है। यदि कोई Sवक्तव्य नहीं था, तो यह एक लूप लूप होगा, और यदि कोई Tवक्तव्य नहीं था, तो यह एक लूप होगा।

इस निर्माण को शून्य या अधिक while Cक्लॉस की अनुमति देकर खुद को सामान्यीकृत किया जा सकता है , जिससे यह अनंत छोरों को व्यक्त करने के लिए एकदम सही हो जाता है और फिर कुछ दुर्लभ स्थितियों में दो चेक की आवश्यकता होती है।

उसी लेख में, नुथ ने एक सिग्नलिंग तंत्र का सुझाव दिया जो अपवादों को फेंकने / पकड़ने का एक स्थानीय संस्करण होगा (गोटो का उपयोग करने के लिए एक विकल्प के रूप में)।

मेरे लिए? मेरी इच्छा है कि जावा समर्थित टेल-कॉल ऑप्टिमाइज़ेशन, ताकि मैं आवश्यकतानुसार किसी भी सामान्य नियंत्रण संरचना को व्यक्त कर सकूँ ।


अद्यतन: मैं यह उल्लेख करना भूल गया कि कई C / C ++ / Java प्रोग्रामर को इसके आस-पास एक असाइनमेंट का उपयोग करके मिलता है while:

while ((c = getc(f)) != -1) {
   T;
}

नुथ के निर्माण से शब्दों का उपयोग करके, यह स्वीकार्य जब है Sऔर Cएक भी अभिव्यक्ति में जोड़ा जा सकता। कुछ लोग उपरोक्त असाइनमेंट को देखने के लिए नफरत करते हैं, जबकि अन्य लोग उपरोक्त breakमें देखने से नफरत करते हैं for (;;)। लेकिन जब Sऔर Cसंयुक्त नहीं किया जा सकता है, जैसे कि जब Sकई कथन हैं, तो for (;;)कोड को दोहराए बिना एकमात्र विकल्प है। अन्य विकल्प केवल Sकोड को डुप्लिकेट करना है :

S;
while (C) {
  T;
  S;
}

नुथ का loop/while/repeatविकल्प ज्यादा बेहतर लगता है।


वह लूप-ए-रिपीट, पास्कल repeat-untilलूप की तरह पूरी तरह दिखता है ।
मेसन व्हीलर

@ मेसन: अंतर यह है कि दो जगह आप बयान दर्ज कर सकते हैं, साथ ही अपनी स्थिति भी।
मैकनील

ओह, मैं देख रहा हूं कि क्या चल रहा है। हाँ, यह दिलचस्प है ...
मेसन व्हीलर

एएनएसआई बेसिक में एक था do while ... loop until- दोनों पूर्व शर्त और पोस्टकंडिशन वैकल्पिक हैं, और मैं (अस्पष्ट रूप से) दोनों को एक लूप में उपयोग करना याद रखता हूं। आपकी मध्य-स्थिति के लिए, वहाँ Ada है exit when ...;। मुख्य लाभ if ... break;यह है कि आप exit loopname when ...;एक से अधिक (लेकिन जरूरी नहीं कि सभी) नेस्टेड छोरों से बाहर निकलने के लिए लिख सकते हैं । उस ब्रेक की तुलना में शायद थोड़ा अधिक दिखाई देता है।
स्टीव 314

हास्यास्पद चीज़। Ada में वह विशेषता है।
जॉन आर। स्ट्रॉह्म

6

बीसीपीएल भाषा में एक valueofअभिव्यक्ति थी जिसका उपयोग बयानों के अनुक्रम को एक एकल अभिव्यक्ति में बदलने के लिए किया जा सकता है:

foo(a, b, valueof {some series of statements; resultis v});

जहां some series of statementsकुछ भी हो सकता है और पूरा valueofमूल्यांकन करता है v

यह जावा में तब आसान हो सकता है जब आपको कॉल करने के लिए एक तर्क की गणना करने की आवश्यकता होती है ( this()या इसके लिए super()कुछ भी नहीं होना चाहिए)। बेशक, आप सिर्फ एक अलग विधि लिख सकते हैं, लेकिन यह एक दर्द हो सकता है यदि आपको संदर्भ के लिए कई स्थानीय मूल्यों में पारित करने की आवश्यकता है।

यदि आप उन finalचर के लिए उपयोग करने में सक्षम हैं जिनकी आवश्यकता है, तो आप पहले से ही valueofजावा में अनाम आंतरिक कक्षाओं का उपयोग कर सकते हैं:

foo(a, b, new Object(){String valueof(){
    String v ...; some series of statements; return v;}}.valueof());

1
जीसीसी के पास इसके लिए एक एक्सटेंशन है - ({ statement1; statement2; ...; result-expr; })। मैंने भी कहीं और ऐसा ही देखा है, लेकिन मुझे याद नहीं है कि कहां। संभवतः सभी BCPL से कॉपी किए गए हैं, हालांकि।
स्टीव 314

6
unless(condition) {
  // ...
}

के रूप में एक ही बात करता है:

if(!condition) {
  // ...
}

repeat {
  // ...
} until(condition)

के रूप में एक ही बात करता है:

do {
  // ...
} while(!condition)

आप लिस्प में जाना चाहते हो सकता है ...
युगल

1
या रूबी, यह के लिए समान वाक्यविन्यास है unless
जोश के

2
काफी पेरिशल लग रहा है। इसे करने का एक से अधिक तरीका है।

2
@ स्टीव 314 आपको गलत ब्रेस स्टाइल का उपयोग करना चाहिए । ;-)
परिक्रमा

1
@ ओबलिंग - बिल्कुल नहीं। हर कोई किसी और एक गलत ब्रेस शैली का उपयोग करता है।
स्टीव

5

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

for (String s, Integer i : stringsSet, integersSet) {
    // use the pair (s, i)
}

कुछ गतिशील भाषाओं में पहले से ही यह हो सकता है, या पुस्तकालयों और मैक्रोज़ के माध्यम से आसानी से समर्थन हो सकता है, लेकिन मुझे लगता है कि यह आपके प्रश्न की भावना में है।

यदि दो सेट एक ही आकार के नहीं हैं, तो यह एक अपवाद फेंक सकता है या आप elseलूप के बाद संकेत देने के लिए हो सकता है कि आकारों में अंतर था।

स्वाभाविक रूप से, आप इसे तीन या अधिक सूचियों के नीचे जाने के लिए सामान्यीकृत कर सकते हैं।


अद्यतन: भी उपयोगी iterables के बीच कार्टेशियन उत्पाद कर रहा होगा:

for (String s, Integer i : stringsSet * integersSet) {
    // use the pair (s, i), each s with each i
}

जो नेस्टेड छोरों से ज्यादा कुछ नहीं होगा:

for (String s : stringsSet) {
    for (Integer i : integersSet) {
        // use the pair (s, i), each s with each i
    }
}

मैं थोड़ा चिंतित हूं कि मैंने जो दो संकेतन यहां दिए हैं, उनमें से केवल एक ही वर्ण के परिवर्तन के साथ जोड़े की संख्या में O (n) और O (n ^ 2) अंतर है।


2
पायथन में जिप और zip_longest हैं जो ऐसा करते हैं।
पिलमंचर

कूल, शायद मैं पायथन को कम आंक रहा हूं और इसे कई वर्षों के बाद दूसरा रूप देना चाहिए। यह मुझे याद दिलाता है, कभी-कभी आप कार्टेशियन उत्पाद भी चाहते हैं, छोरों के लिए नेस्टेड के बराबर।
मैकनील


1
कार्टेशियन उत्पाद के संदर्भ में: फिर से, पायथन के पास है। for a, b, c in itertools.product(iter1, iter2, iter3):आप कार्टेसियन उत्पाद का आलसी मूल्यांकन करता है। वह क्या है? आप किसी दिए गए पुनरावृत्ति के क्रमपरिवर्तन और संयोजन भी चाहते हैं? itertools.permutations, itertools.combinations
aaronasterling

1
हास्केल परिप्रेक्ष्य: पहले मामले के लिए "ज़िपविथ" का उपयोग करें और दूसरे के लिए सूची समझ या सूची का उपयोग करें। जैसे पायथन / स्काला निर्वासित, लेकिन अधिक सुरुचिपूर्ण। :)
लेनीप्रोग्रामर्स

5

तथाकथित "डेज्क्स्ट्रा का लूप" (जिसे "डिक्जस्ट्रा का गार्ड लूप" भी कहा जाता है)। इसे द गार्डेड कमांड लैंग्वेज (GCL) में परिभाषित किया गया था । आप इसके बारे में कुछ जानकारी पा सकते हैं। सिंटैक्स और अर्थ विकिपीडिया के उपरोक्त लेख में ६ पुनरावृत्ति: खंड में ।

आजकल मैं वास्तव में एक प्रोग्रामिंग भाषा जानता हूं जो इस नियंत्रण को सीधे सीवन का समर्थन करता है। यह ओबेरॉन -07 (पीडीएफ, 70 केबी) है। और यह कथन के रूप में "दिज्क्स्ट्रा के पाश" का समर्थन करता है। धारा 9.6 पर एक नज़र डालें। जबकि उपरोक्त पीडीएफ में बयान।

WHILE m > n DO m := m – n 
ELSIF n > m DO n := n – m 
END

PS यह मेरे एसओ उत्तर की प्रति है ।


मॉडल चेकर की तरह दिखता है स्पिन में भी यह निर्माण होता है, समान शब्दार्थ और मूल रूप से समान वाक्यविन्यास के साथ।
j_random_hacker

4

अंतर्निहित बैकट्रैकिंग के साथ आइकन-शैली के भाव।

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

x = (a / b) else c;

शून्य द्वारा विभाजन जैसे असफल मामलों को संभालने के लिए।

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

मैं हमेशा सोचता था कि उनके पास ifकोई और हिस्सा नहीं होना चाहिए - इस if (condition, success-value)तरह की बात, अगर स्थिति झूठी हो जाए तो पीछे हट जाना - और अजीब तुलना छोड़ देना।

EDIT मुझे याद है - वास्तव में स्पष्ट है। दो तर्कों के साथ तुलना या तो सफल होती है या विफल होती है - यह लौटने के लिए एक नए मूल्य की गणना नहीं करता है। तो जब यह सफल होता है, क्या करता है इसे वापस? उत्तर - तर्कों में से एक। लेकिन अगर आप लिखते हैं a > b, जो लौटना तार्किक तर्क है - aया b? और अगर आप b < aइसके बजाय लिखते हैं तो क्या होगा ? मुझे लगता है कि यह हमेशा सही तर्क देता था, जो कि किसी भी चीज के रूप में अधिक समझ में आता है, लेकिन यह आमतौर पर मुझे गलत तर्क की तरह लग रहा था।


4

यह केवल एक सामान्य विचार और वाक्य रचना है:

if (cond)
   //do something
else (cond)
   //do something
also (cond)
   //do something
else
   //do something
end

ALSO की स्थिति का हमेशा मूल्यांकन किया जाता है। ELSE हमेशा की तरह काम करता है।

यह केस के लिए भी काम करता है। संभवतः यह ब्रेक स्टेटमेंट को खत्म करने का एक अच्छा तरीका है:

case (exp)
   also (const)
      //do something
   else (const)
      //do something
   also (const)
      //do something
   else
      //do something
end

के रूप में पढ़ा जा सकता है:

switch (exp)
   case (const)
      //do something
   case (const)
      //do something
      break
   case (const)
      //do something
   default
      //do something
end

मुझे नहीं पता कि यह उपयोगी है या पढ़ने में सरल है लेकिन यह एक उदाहरण है।


3

कंटीन्यू पासिंग स्टाइल दिमाग में आती है। फिर, निश्चित रूप से, आप टेल कॉल ऑप्टिमाइज़ेशन भी करना चाहेंगे ।


1
इसका एक बहुत बड़ा प्रशंसक नहीं है, और मुझे विश्वास नहीं है कि यह वास्तव में एक "नियंत्रण संरचना" है, बल्कि कार्यात्मक भाषाओं और प्रोग्रामिंग शैली में एक बिल्डिंग ब्लॉक है। Node.js लगता है हालांकि इस पर झुका हुआ है।
जोश के

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

1
आपको इन दिनों C और C ++ में टेल कॉल ऑप्टिमाइज़ेशन मिलता है, लेकिन IMO में यह बात याद आती है। मुद्दा यह है कि यह है है एक अनुकूलन। योजना में, एक वास्तविक पूंछ कॉल स्पष्ट है। विशेष रूप से C ++ में, कई चीजों का मतलब हो सकता है कि आपकी टेल कॉल टेल कॉल नहीं है। और स्टैक ओवरफ्लो का मतलब है कि आपका ऐप टूट गया है। IMO, एक goto return ...;स्टेटमेंट जैसा कुछ होना चाहिए , जिससे टेल-कॉल का इरादा स्पष्ट हो, इसलिए यदि कंपाइलर इसे पुनरावृत्त नहीं बना सकता है तो यह एक त्रुटि है।
314

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

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

3

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

branch foo(data, to, be, processed){
    //code
    return [resulting, data]
}

जब एक शाखा कहा जाता है तो यह तुरंत एक हैंडल लौटाएगा।

handle=foo(here, is, some, data)

यदि कार्य किया जाता है, तो यह जांचने के लिए हैंडल का उपयोग किया जा सकता है।

handle.finished() //True if the execution is complete

यदि निष्पादन के पूरा होने से पहले परिणाम का अनुरोध किया जाता है, तो मुख्य धागा बस इंतजार करेगा।

[result, storage]=handle.result()

यह अधिक उन्नत मल्टीथ्रेडिंग परिदृश्यों को कवर नहीं करेगा, बल्कि कई कोर का उपयोग करने के लिए शुरुआत का एक सहज सुलभ तरीका प्रदान करेगा।


Cilk पर एक नज़र डालें, यह C का बहुत साफ और सरल विस्तार है: en.wikipedia.org/wiki/Cilk । मैं नहीं जानता कि अगर यह एक है handle.finished()परीक्षण, लेकिन spawnऔर syncतुम सब समानांतर प्रोग्रामिंग कार्यों में से 90% के लिए की जरूरत है।
j_random_hacker

3
if (cond)
   //do something
else (cond)
   //do something
else (cond)
   //do something
first
   //do something
then
   //do something
else (cond)
   //do something
else
   //do something
end

यदि किसी भी 3 शर्त का सही मूल्यांकन किया जाता है तो FIRST और THEN ब्लॉक चलता है। एफआईएसटी ब्लॉक सशर्त ब्लॉक से पहले चलता है और यह सशर्त ब्लॉक चलाने के बाद चलता है।

FIRST के बाद ELSE सशर्त या अंतिम लेखन इन ब्लॉकों से स्वतंत्र हैं।

यह इस प्रकार पढ़ सकता है:

if (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   first()
   //do something
   then()
else (cond)
   //do something
else
   //do something
end


function first()
   //do something
return
function then()
   //do something
return

ये कार्य केवल पढ़ने के लिए एक रूप हैं। वे गुंजाइश पैदा नहीं करेंगे। यह एक गोसुब / बेसिक से वापसी की तरह है।

चर्चा के विषय के रूप में उपयोगिता और पठनीयता।


2

मैं कभी-कभी खुद को एक लूप लिखता हुआ पाता हूं, जिसे पहली पुनरावृत्ति के दौरान कुछ अलग करने की आवश्यकता होती है। उदाहरण के लिए, <td> टैग के बजाय <th> टैग प्रदर्शित करना।

मैं बूलियन ध्वज के साथ इस स्थिति को संभालता हूं। कुछ इस तरह:

first = true

while (some_condition)
    if (first)
        do_something
        first = false
    else
        do_something_else

के मूल्य की जांच करना मूर्खतापूर्ण लगता है first हर पुनरावृत्ति जब यह अधिकांश समय गलत होने वाला हो।

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


SO प्रश्न का एक समान विचार है, लेकिन मूल्यों पर उपयोग किए जाने वाले "तत्कालीन" ऑपरेटर के साथ। इस तरह, आपके पास शायद डुप्लिकेट कोड नहीं है। जैसेprint(out, first "<th>" then "<td>")
मैकनील

1
बेहतर तरीका है कि या तो पुनरावृति +1 को शुरू करें।
जोश के

1
कॉमन सेपरेटर के साथ सामान की लिस्टिंग के लिए कॉमन केस, हैंडलिंग के बीच लूपिंग है। कड़ाई से, यह if (!first) gimme-a-comma ();, लेकिन बहुत कुछ एक ही बात है। एक आपत्ति होगी, हालांकि - यदि आप इसे उचित रूप से लपेटते हैं तो आप पायथन स्ट्रिंग में शामिल होने की विधि जैसी चीजों के साथ समाप्त हो जाते हैं - हालांकि अक्सर आपको मूल पैटर्न की आवश्यकता होती है, अंतर्निहित लूप को फिर से लिखने की आवश्यकता नहीं होती है।
स्टीव 314

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

1
@ बैरी ब्राउन: लूप के 1 पुनरावृत्ति को अनियंत्रित करना बूलियन ध्वज की जांच से तेज हो सकता है या नहीं भी हो सकता है। एक सभ्य शाखा प्रेडिक्टर सबसे खराब 1 2 पुनरावृत्तियों पर गलत निर्णय लेगा, मैं भविष्यवाणी करता हूं :) मैं उपयोग करना पसंद करूंगा if (!first)और एक अनुकूलन संकलक को यह तय करने दूंगा कि क्या लूप बॉडी काफी छोटी है कि अनियंत्रित हो रही है और छुटकारा पा रही firstहै।
j_random_hacker 7

1

[स्टैकओवरफ़्लो पर मेरे अपने जवाब से कॉपी किया गया]


ignoring - कोड के एक निश्चित ब्लॉक में होने वाले अपवादों को अनदेखा करना।

try {
  foo()
} catch {
  case ex: SomeException => /* ignore */
  case ex: SomeOtherException => /* ignore */
}

एक अनदेखी नियंत्रण निर्माण के साथ, आप इसे अधिक संक्षेप में और अधिक आसानी से लिख सकते हैं:

ignoring(classOf[SomeException], classOf[SomeOtherException]) {
  foo()
}

[Scala इसे (और कई अन्य अपवाद हैंडलिंग नियंत्रण निर्माण प्रदान करता है) अपने मानक पुस्तकालय में, use.control पैकेज में। ]


4
अपवादों को अनदेखा नहीं किया जाना चाहिए।
जोश के

1
सिवाय इसके कि, संदर्भ में, एक त्रुटि नहीं हो सकती है।
314

1
@Josh, @Steve: ऐसे मामले हैं जब आप अपवादों को अनदेखा करना चाहेंगे। इस तरह के कुछ मामलों के लिए इस धागे को देखें ।
लापता

एक अपवाद एक चेतावनी है कि कुछ गलत हो सकता है। एक खाली try..catchब्लॉक एक बात है; यह आपको त्रुटि को पहचानने और जानबूझकर इसे अनदेखा करने के लिए मजबूर करता है; एक वैश्विक अनदेखी के तहत कोड का हिस्सा फेंकने पर उन मुद्दों को जन्म दे सकता है जब उन अपवादों को फेंक दिया जाता है, साथ ही साथ खराब प्रोग्रामिंग आदतों के लिए नेतृत्व किया जाता है।
जोश के

@ जोश - सिर्फ दो टिप्पणियों को हटा दिया क्योंकि मैं सीधे नहीं सोच रहा था - लेकिन इस एक के लिए उम्मीदें अधिक हैं। यदि यह कथन वैश्विक है, तो मैं शायद सहमत हूं - लेकिन यह मेरे लिए एक ब्लॉक संरचना की तरह दिखता है। IOW यह एक tryब्लॉक की तरह है , इसके अलावा यह अपवादों को सूचीबद्ध करता है जो इसे पकड़ता है और बाद में इसके बजाय सामने की अनदेखी करता है। यह पठनीयता का लाभ भी हो सकता है - उदाहरण के तौर पर पाठक को यह पता होना चाहिए कि खुली कॉल को पढ़ने से पहले एक लापता फाइल में कोई त्रुटि नहीं है।
स्टीव

1

के बजाय:

switch(myEnum) {
  case MyEnum.Val1: do1(); ...
  case MyEnum.Val2: do2(); ...
....

इसे अजगर करें, या अब C # तरीका भी:

action = val2func[myEnum]
action()

स्काला में बहुत सारी नई विशेषताएं हैं।

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


1
C यह भी कर सकता है। और पास्कल। शायद उन सभी पुराने 70/80/90 के दशक की भाषाएं। फ़ंक्शन का एक प्रकार फ़ंक्शन पॉइंटर्स का एक सरणी बन जाता है, लेकिन यह कोई बड़ी बात नहीं है। जहां यह आसान हो जाता है जब आपको अनाम कार्य मिलते हैं - आप जानते हैं, जैसे लिस्प में, एमएल, ...
स्टीव 314

स्टीव 314 - सुधार - यह एक शब्दकोश का एक उदाहरण है जो किसी फ़ंक्शन के लिए किसी भी मूल्य को मैप करता है। यह वह जगह है जहां चीजें 70/80/90 के दशक की अधिकांश चीजों की तुलना में थोड़ी साफ हो जाती हैं।
जॉब

1

मेरे दो विचार हैं।

अक्सर मुझे लगता है कि मैं खुद को catchब्लॉकों में दोहरा रहा हूं । इसे निकालने के तरीकों के माध्यम से कुछ हद तक मदद की जा सकती है, लेकिन यह अनावश्यक अव्यवस्था पैदा कर सकता है यदि विधियां बहुत कम हैं या अन्यथा विधि के योग्य नहीं हैं। तो, यह घोंसला catchब्लॉक के लिए अच्छा होगा :

try {
    // Save something
} catch (Exception e) {
    // Something we do for all Exceptions
    catch (ProcessingException e) {
        // Something we do for all Processing exceptions
        catch (DBExcpetion e) {
            // DBExceptions are a subclass of ProcessingException
        }
        catch (BusinessRuleException e) {
            // BusinessRuleExceptions are also a subclass of ProcessingException
        }
    }
    // Something we do after specific sub class Exceptions
 }

वेब प्रोग्रामिंग में, मैं अक्सर खुद को अक्सर ऐसा कुछ करते हुए पाता हूं (यह एक वास्तविक उदाहरण नहीं है इसलिए काल्पनिक मामलों का विश्लेषण नहीं करें):

Account a = getSavedAccount();
if (a == null) {
    a = getAccountFromSessionId();
}
if (a == null) {
    a = getAccountFromCookieId();
}
if (a == null) {
    a = createNewAccount();
}

जावास्क्रिप्ट में (अच्छी तरह से, ईसीएमएस्क्रिप्ट, और शायद अन्य जो मैं अपरिचित हूं), चूंकि किसी भी मूल्य का एक शर्त के रूप में मूल्यांकन किया जा सकता है, ||मदद कर सकता है।

var a = getAFromLocation1() || getAFromLocation2() || default;

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


अजगर तेरे जैसा कुछ करता है || मूल्यांकन, लेकिन जब इसे आखिरकार इसकी सशर्त अभिव्यक्ति x if c else yसिंटैक्स मिला , तो एक बड़ा कारण यह हुआ कि इन अर्थों का उपयोग करने वाले बहुत सारे अभिव्यक्ति थे ||और &&सूक्ष्म रूप से छोटी गाड़ी थी। IIRC एक सामान्य मामला एक मूल्य था (जैसे कि शून्य) जो कि falseइस तरह से व्यवहार किए जा रहे अनुप्रयोग के लिए मान्य था , इसलिए इसे छोड़ दिया गया, ताकि इसके बजाय एक अमान्य फ़ॉलबैक का उपयोग किया गया। हालाँकि - मेरा जवाब WRT द आइकॉन प्रोग्रामिंग लैंग्वेज देखें, जिसमें एक्सप्रेशन जैसे भाव हो सकते हैं get1() else get2() else default
स्टीव

1

सामान्यीकृत स्विच ने ऊपर कहा है:

 switch(x){
  predicate1:
     dosomething();
  predicate2:
     dosomethingelse();
 }

हास्केल में:

  switch' :: a -> [(a -> Bool, b)] -> b
  switch' a [] = undefined
  switch' a (f,b):xs = if f a
                     then b
                      else switch' a xs

0

C # में मैं सरल switch () { ... }, लेकिन इस तरह के भावों के साथ विस्तार करना चाहूंगा :

switch (value)
{
  // string-based operators:
  case begins "Maria": // to catch Maria Carey
    break;
  case ends "Washington": // to catch George Washington
    break;
  case like "ph": // to catch Phil, Phillip, Sophie
    break;
  case between "Aaron" and "April": // to catch all names between
    break;

  // use non-static variables in case expression:
  case Dao.GetDefaultBabyName():
    break;

  // continuable cases without breaking
  case "John":
    bonus = 25;
  case "Peter":
    salary = 500;
    break;

  // jumps between cases
  case "Aleron":
    // do something
    break;
  case "Bella":
    // do something
    jump "Aleron";
    break;

}

और इसी तरह। संख्याओं या अन्य प्रकारों के साथ एक ही (जो समर्थन करता है IComparable,IConvertible , ...)

यह मेरे कोड को अधिक स्पष्ट और पठनीय बना सकता है।


मामलों पर गिरना एक ज्ञात बुराई है, और मैं आम तौर पर इसके बिना ठीक हूं। और कूदता है किसी भी प्रोग्रामिंग के लिए बहुत GOTOish है। लेकिन इस मामले में भाव और गैर-स्टेटिक्स एक प्यारा जोड़ होगा।
कोडेक्सअर्बनम

0

यह एक मजेदार सवाल है, जैसा @Macneil ने कहा।

मेरी पसंदीदा असामान्य नियंत्रण संरचना, जिसे मैंने (विनम्र खाँसी) खोजा, अंतर निष्पादन है

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

आमतौर पर मैं इसे मैक्रोज़ द्वारा C या C ++ में लागू करता हूं। C # में मुझे इसे हाथ से विस्तार करने वाले कथनों द्वारा करना है। यह एक दर्द है, लेकिन यह काम करता है।

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


0

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

सत्ता से लड़ना!


0

सबसे सरल forलूप-

for(100)
{
    //Will run for 100 times
}


for(i)
{
    //Will run for i times while i must be a positive integer
}


for(i as a)
{
    //Will run for i times while i must be a positive integer
    //and a is the incremental loop variable starting from 0 and 
    //scoped within the loop
}


for(i as a=2)
{
    //Will run for i times while i must be a positive integer
    //and a is the incremental loop variable starting from 2 and 
    //scoped within the loop
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.