www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Loop iterator - example.txt

reply Rick C. Hodgin <Rick_member pathlink.com> writes:
Here's an idea:

There should be a way in D to allow the reconsideration of a for..loop test
clause without executing the increment clause.

Using the terminology:
for (initialize-clause; conditional-clause; increment-clause)

Example:
int i;
for (i=0; i<10; i++)
{
if (string.substr(i,1) == something)
{
i += some_other_function();
retry;
}
else if (string.substr(i,1) == something_else)
{
i += some_other_function2();
retry;
}
// Otherwise, simply execute the "i++" and re-test
}

I propose the name "retry" for the "retest without increment-clause" command, to
be used in a manner similar syntax-wise to the way "break" is used today.
"Retry" would simply bypass the increment-clause and proceed straight to the
conditional-clause code section, thereby allowing subsequent passes through the
for loop without the requisite and occasionally unnecessary auto-incrementation.

It would just be a way to give for loops a little more natural utility without
having to do some rather obtuse programming techniques, such as using goto's or
enclosing the code in a while or do loop, etc.

- Rick C. Hodgin
Apr 28 2006
next sibling parent "Derek Parnell" <derek psych.ward> writes:
On Sat, 29 Apr 2006 06:31:07 +1000, Rick C. Hodgin  
<Rick_member pathlink.com> wrote:

 Here's an idea:

 There should be a way in D to allow the reconsideration of a for..loop  
 test
 clause without executing the increment clause.

...
 I propose the name "retry" for the "retest without increment-clause"  
 command, to
 be used in a manner similar syntax-wise to the way "break" is used today.

Yes! I use this construct daily with the Progress 4GL our company employs. It elegantly implements a common idiom without a whole lot of twisting and obscurity. -- Derek Parnell Melbourne, Australia
Apr 28 2006
prev sibling next sibling parent "Craig Black" <cblack ara.com> writes:
"Rick C. Hodgin" <Rick_member pathlink.com> wrote in message
news:e2tu2b$kv8$1 digitaldaemon.com...
 Here's an idea:

 There should be a way in D to allow the reconsideration of a for..loop

 clause without executing the increment clause.

 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)

 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }

 I propose the name "retry" for the "retest without increment-clause"

 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to

 conditional-clause code section, thereby allowing subsequent passes

 for loop without the requisite and occasionally unnecessary

 It would just be a way to give for loops a little more natural utility

 having to do some rather obtuse programming techniques, such as using

 enclosing the code in a while or do loop, etc.

Very good idea. I find myself decrementing the iterator in order to achieve the same. This approach doesn't work in more complex cases and I've recently run into a complex situation where "retry" would have saved me a lot of headaches. -Craig
Apr 28 2006
prev sibling next sibling parent Alexander Panek <alexander.panek brainsware.org> writes:
Rick C. Hodgin wrote:
 Here's an idea:
 
 There should be a way in D to allow the reconsideration of a for..loop test
 clause without executing the increment clause.
 
 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)
 
 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }
 
 I propose the name "retry" for the "retest without increment-clause" command,
to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to the
 conditional-clause code section, thereby allowing subsequent passes through the
 for loop without the requisite and occasionally unnecessary
auto-incrementation.
 
 It would just be a way to give for loops a little more natural utility without
 having to do some rather obtuse programming techniques, such as using goto's or
 enclosing the code in a while or do loop, etc.
 
 - Rick C. Hodgin
 
 
 
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

Very neat, got my vote! Regards, Alexander Panek
Apr 29 2006
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
Rick C. Hodgin wrote:
 
 I propose the name "retry" for the "retest without increment-clause" command,
to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to the
 conditional-clause code section, thereby allowing subsequent passes through the
 for loop without the requisite and occasionally unnecessary
auto-incrementation.

I like it. It would be particularly nice if this were made to work with foreach as well, since there's currently no way to avoid progress for each iteration. Sean
Apr 29 2006
prev sibling next sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Rick C. Hodgin wrote:
 Here's an idea:
 
 There should be a way in D to allow the reconsideration of a for..loop test
 clause without executing the increment clause.
 
 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)
 
 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }
 
 I propose the name "retry" for the "retest without increment-clause" command,
to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to the
 conditional-clause code section, thereby allowing subsequent passes through the
 for loop without the requisite and occasionally unnecessary
auto-incrementation.
 
 It would just be a way to give for loops a little more natural utility without
 having to do some rather obtuse programming techniques, such as using goto's or
 enclosing the code in a while or do loop, etc.
 
 - Rick C. Hodgin
 
 
 
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

For the case where you don't have any continues, you can do the code this way instead: for (i=0; i<10; ) { if (string.substr(i,1) == something) { i += some_other_function(); continue; } else if (string.substr(i,1) == something_else) { i += some_other_function2(); continue; } // ############ Execute the increment expression here: ####### i++; } The remaining case, where you want to use continues and retries in the same for, well, I don't think it's a common enough case that makes it worth the introduction of a new keyword just some trivial syntactic sugar. In fact, the very idea seems like a very awkward idiom to me. I would like to examine a real example, can someone post one? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 29 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Sun, 30 Apr 2006 06:02:10 +1000, Bruno Medeiros  
<brunodomedeirosATgmail SPAM.com> wrote:


 In fact, the very idea seems like a very awkward idiom to me. I would  
 like to examine a real example, can someone post one?

We use it in the area of retrying a database transaction after some sort of exception condition has happened. It has nothing directly to do with loop index maintenance. In pseudo-code ... foreach (inout Customer cust; CustomerSet ) { try { cust.name = UI.CustName; cust.address = UI.Address; . . . } catch (BadUI e) { // Recover from the (rare) UI data error . . . retry; // Reprocess the same customer record. } } -- Derek Parnell Melbourne, Australia
Apr 29 2006
parent reply kris <foo bar.com> writes:
Derek Parnell wrote:
 On Sun, 30 Apr 2006 06:02:10 +1000, Bruno Medeiros  
 <brunodomedeirosATgmail SPAM.com> wrote:
 
 
 In fact, the very idea seems like a very awkward idiom to me. I would  
 like to examine a real example, can someone post one?

We use it in the area of retrying a database transaction after some sort of exception condition has happened. It has nothing directly to do with loop index maintenance. In pseudo-code ... foreach (inout Customer cust; CustomerSet ) { try { cust.name = UI.CustName; cust.address = UI.Address; . . . } catch (BadUI e) { // Recover from the (rare) UI data error . . . retry; // Reprocess the same customer record. } }

Does that retry that instance, or retry the entire loop? Couldn't the semantics be either, given the appropriate condition?
Apr 29 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Sun, 30 Apr 2006 10:28:13 +1000, kris <foo bar.com> wrote:

 Derek Parnell wrote:
 On Sun, 30 Apr 2006 06:02:10 +1000, Bruno Medeiros   
 <brunodomedeirosATgmail SPAM.com> wrote:

 In fact, the very idea seems like a very awkward idiom to me. I would   
 like to examine a real example, can someone post one?

sort of exception condition has happened. It has nothing directly to do with loop index maintenance. In pseudo-code ... foreach (inout Customer cust; CustomerSet ) { try { cust.name = UI.CustName; cust.address = UI.Address; . . . } catch (BadUI e) { // Recover from the (rare) UI data error . . . retry; // Reprocess the same customer record. } }

Does that retry that instance, or retry the entire loop? Couldn't the semantics be either, given the appropriate condition?

Just the instance and not the entire loop. There is a 'restart' key word to do the whole loop thing. -- Derek Parnell Melbourne, Australia
Apr 29 2006
parent kris <foo bar.com> writes:
Derek Parnell wrote:
 On Sun, 30 Apr 2006 10:28:13 +1000, kris <foo bar.com> wrote:
 
 Derek Parnell wrote:

 On Sun, 30 Apr 2006 06:02:10 +1000, Bruno Medeiros   
 <brunodomedeirosATgmail SPAM.com> wrote:

 In fact, the very idea seems like a very awkward idiom to me. I 
 would   like to examine a real example, can someone post one?

We use it in the area of retrying a database transaction after some sort of exception condition has happened. It has nothing directly to do with loop index maintenance. In pseudo-code ... foreach (inout Customer cust; CustomerSet ) { try { cust.name = UI.CustName; cust.address = UI.Address; . . . } catch (BadUI e) { // Recover from the (rare) UI data error . . . retry; // Reprocess the same customer record. } }

Does that retry that instance, or retry the entire loop? Couldn't the semantics be either, given the appropriate condition?

Just the instance and not the entire loop. There is a 'restart' key word to do the whole loop thing.

Thanks; I had missed the 'restart'; - Kris
Apr 29 2006
prev sibling parent Dan <Dan_member pathlink.com> writes:
 In pseudo-code ...
 
    foreach (inout Customer cust; CustomerSet )
    {
        try {
        cust.name = UI.CustName;
        cust.address = UI.Address;
        . . .
        }
        catch (BadUI e)
        {
            // Recover from the (rare) UI data error
            . . .
            retry; // Reprocess the same customer record.
        }
    }
 

Does that retry that instance, or retry the entire loop? Couldn't the semantics be either, given the appropriate condition?

Fortunately, it's not ambiguous. The try/catch is INSIDE the loop, so it will continue the loop where it left off once the error is handled. If the try/catch were outside the loop, it would run the whole loop over again. I don't think it's really that difficult; and no, you can't separate the try/catch and have one in and one out. That's a syntax error. If you throw errors and catch them elsewhere, my understanding is that the program *should* resume at the end of the try block once it's handled. Please correct me if I'm wrong. Also, unless some method is throwing an error, I highly recommend simply using if or assert instead of try/catch. I *think* try/catch is traditionally done through a very time consuming system fault mechanism, whereas if/assert are simply a "short jcc" instruction.
Apr 29 2006
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Bruno Medeiros wrote:
 
 The remaining case, where you want to use continues and retries in the 
 same for, well, I don't think it's a common enough case that makes it 
 worth the introduction of a new keyword just some trivial syntactic sugar.
 In fact, the very idea seems like a very awkward idiom to me. I would 
 like to examine a real example, can someone post one?

Deleting selected members of a sequence: for( int i = 0; i < a.length; ++i ) { if( isMatch( a[i] ) ) { swap( a[i], a[$-1] ); a.length = a.length - 1; retry; } } Sean
Apr 29 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Sean Kelly wrote:
 Bruno Medeiros wrote:
 The remaining case, where you want to use continues and retries in the 
 same for, well, I don't think it's a common enough case that makes it 
 worth the introduction of a new keyword just some trivial syntactic 
 sugar.
 In fact, the very idea seems like a very awkward idiom to me. I would 
 like to examine a real example, can someone post one?

Deleting selected members of a sequence: for( int i = 0; i < a.length; ++i ) { if( isMatch( a[i] ) ) { swap( a[i], a[$-1] ); a.length = a.length - 1; retry; } } Sean

I was thinking of an example which used continues and retries in the same for, as yours can be cleanly rewritten as the example in my later post. Anyway, Derek's example serves as a good example of the keyword's usage, but for "foreach", for "for" I'm still finding it a bit odd. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 30 2006
parent reply Sean Kelly <sean f4.ca> writes:
Bruno Medeiros wrote:
 
 I was thinking of an example which used continues and retries in the 
 same for, as yours can be cleanly rewritten as the example in my later 
 post.
 Anyway, Derek's example serves as a good example of the keyword's usage, 
 but for "foreach", for "for" I'm still finding it a bit odd.

I think it's more useful for "foreach" because there's no way to avoid progressing with each iteration. However, goto still works here as in Walter's example. "retry" is handy, but it's more a convenience than anything. Sean
Apr 30 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Mon, 01 May 2006 05:18:11 +1000, Sean Kelly <sean f4.ca> wrote:

 Bruno Medeiros wrote:
  I was thinking of an example which used continues and retries in the  
 same for, as yours can be cleanly rewritten as the example in my later  
 post.
 Anyway, Derek's example serves as a good example of the keyword's  
 usage, but for "foreach", for "for" I'm still finding it a bit odd.

I think it's more useful for "foreach" because there's no way to avoid progressing with each iteration. However, goto still works here as in Walter's example. "retry" is handy, but it's more a convenience than anything.

And *expressive*. That is, it signals the coder's intent more clearly than a goto can because in theory the goto can go to anywhere but that is not the case with 'retry'. Thus the use of 'retry' is more likely to lead to less misunderstanding and bugs. So even though it is a 'goto' in disguise, it is a controlled goto. -- Derek Parnell Melbourne, Australia
Apr 30 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Derek Parnell wrote:
 On Mon, 01 May 2006 05:18:11 +1000, Sean Kelly <sean f4.ca> wrote:
 
 Bruno Medeiros wrote:
  I was thinking of an example which used continues and retries in the 
 same for, as yours can be cleanly rewritten as the example in my 
 later post.
 Anyway, Derek's example serves as a good example of the keyword's 
 usage, but for "foreach", for "for" I'm still finding it a bit odd.

I think it's more useful for "foreach" because there's no way to avoid progressing with each iteration. However, goto still works here as in Walter's example. "retry" is handy, but it's more a convenience than anything.

And *expressive*. That is, it signals the coder's intent more clearly than a goto can because in theory the goto can go to anywhere but that is not the case with 'retry'. Thus the use of 'retry' is more likely to lead to less misunderstanding and bugs. So even though it is a 'goto' in disguise, it is a controlled goto. --Derek Parnell Melbourne, Australia

Hum, now that you mention it, what if goto could only jump to labels that are lexically visible in the current scope, using the same rules as variables. Seems to me it would make goto more safe, but is such behavior acceptable? I mean, is there a reasonable use scenario for goto that requires a cross-scope jump? (I wonder if any of the cases presented by Walter would require such thing) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 01 2006
parent reply "Chris Miller" <chris dprogramming.com> writes:
On Mon, 01 May 2006 05:36:56 -0400, Bruno Medeiros  
<brunodomedeirosATgmail SPAM.com> wrote:

 Hum, now that you mention it, what if goto could only jump to labels  
 that are lexically visible in the current scope, using the same rules as  
   variables. Seems to me it would make goto more safe, but is such  
 behavior acceptable? I mean, is there a reasonable use scenario for goto  
 that requires a cross-scope jump? (I wonder if any of the cases  
 presented by Walter would require such thing)

C# has a restriction similar to this and it's pretty annoying. if(something) goto mylabel; // error, mylabel not in scope. stuff(); if(somethingelse) { mylabel: morestuff(); }
May 01 2006
next sibling parent reply Alexander Panek <alexander.panek brainsware.org> writes:
Chris Miller wrote:
 On Mon, 01 May 2006 05:36:56 -0400, Bruno Medeiros 
 <brunodomedeirosATgmail SPAM.com> wrote:
 
 Hum, now that you mention it, what if goto could only jump to labels 
 that are lexically visible in the current scope, using the same rules 
 as   variables. Seems to me it would make goto more safe, but is such 
 behavior acceptable? I mean, is there a reasonable use scenario for 
 goto that requires a cross-scope jump? (I wonder if any of the cases 
 presented by Walter would require such thing)

C# has a restriction similar to this and it's pretty annoying. if(something) goto mylabel; // error, mylabel not in scope. stuff(); if(somethingelse) { mylabel: morestuff(); }

if ( !something ) { stuff( ); } else if ( somethingelse ) { morestuff( ); } ?
May 01 2006
parent "Chris Miller" <chris dprogramming.com> writes:
On Mon, 01 May 2006 09:30:26 -0400, Alexander Panek  
<alexander.panek brainsware.org> wrote:

 Chris Miller wrote:
 On Mon, 01 May 2006 05:36:56 -0400, Bruno Medeiros  
 <brunodomedeirosATgmail SPAM.com> wrote:

 Hum, now that you mention it, what if goto could only jump to labels  
 that are lexically visible in the current scope, using the same rules  
 as   variables. Seems to me it would make goto more safe, but is such  
 behavior acceptable? I mean, is there a reasonable use scenario for  
 goto that requires a cross-scope jump? (I wonder if any of the cases  
 presented by Walter would require such thing)

if(something) goto mylabel; // error, mylabel not in scope. stuff(); if(somethingelse) { mylabel: morestuff(); }

if ( !something ) { stuff( ); } else if ( somethingelse ) { morestuff( ); }

Not the point, this is a small example that isn't real; besides, check your logic (something=false; somethingelse=true;)
May 01 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Chris Miller wrote:
 On Mon, 01 May 2006 05:36:56 -0400, Bruno Medeiros 
 <brunodomedeirosATgmail SPAM.com> wrote:
 
 Hum, now that you mention it, what if goto could only jump to labels 
 that are lexically visible in the current scope, using the same rules 
 as   variables. Seems to me it would make goto more safe, but is such 
 behavior acceptable? I mean, is there a reasonable use scenario for 
 goto that requires a cross-scope jump? (I wonder if any of the cases 
 presented by Walter would require such thing)

C# has a restriction similar to this and it's pretty annoying. if(something) goto mylabel; // error, mylabel not in scope. stuff(); if(somethingelse) { mylabel: morestuff(); }

Actually, based on some previous notion that I don't where I got it from, and from Derek's comments, I thought /goto/ (in both D and C) could jump anywhere in the code, even across functions :o I've only found out now that that is not the case, and that was the most of the idea of my restriction. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 03 2006
prev sibling next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Rick C. Hodgin wrote:
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

I know goto's are evil, but I tend to write such as: int i; for (i=0; i<10; i++) { Lretry: if (string.substr(i,1) == something) { i += some_other_function(); goto Lretry; } else if (string.substr(i,1) == something_else) { i += some_other_function2(); goto Lretry; } // Otherwise, simply execute the "i++" and re-test }
Apr 29 2006
next sibling parent reply Alexander Panek <alexander.panek brainsware.org> writes:
Walter Bright wrote:
 Rick C. Hodgin wrote:
 
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

I know goto's are evil, but I tend to write such as: int i; for (i=0; i<10; i++) { Lretry: if (string.substr(i,1) == something) { i += some_other_function(); goto Lretry; } else if (string.substr(i,1) == something_else) { i += some_other_function2(); goto Lretry; } // Otherwise, simply execute the "i++" and re-test }

How about we all try to avoid GOTOs and you implement this keyword? :P Regards, Alexander Panek
Apr 30 2006
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
At the risk of asking a stupid question, what is wrong with gotos?

I realize they can result in code that people with insufficient 
programming experience might not understand (and I'm not trying to be 
arrogant here, because I avoid using gotos for exactly and only this 
reason, I don't use or read them enough.)

But that doesn't seem reason enough for everyone to hate them.  If I see 
a need for one, I use it - and I add comments to make sure no one gets 
confused.

Is the only reason that people fear them, or is there a real legitimate 
reason?

-[Unknown]


 How about we all try to avoid GOTOs and you implement this keyword? :P
 
 Regards,
 Alexander Panek

Apr 30 2006
next sibling parent reply Alexander Panek <alexander.panek brainsware.org> writes:
Unknown W. Brackets wrote:
 At the risk of asking a stupid question, what is wrong with gotos?
 
 I realize they can result in code that people with insufficient 
 programming experience might not understand (and I'm not trying to be 
 arrogant here, because I avoid using gotos for exactly and only this 
 reason, I don't use or read them enough.)
 
 But that doesn't seem reason enough for everyone to hate them.  If I see 
 a need for one, I use it - and I add comments to make sure no one gets 
 confused.
 
 Is the only reason that people fear them, or is there a real legitimate 
 reason?
 
 -[Unknown]
 
 
 How about we all try to avoid GOTOs and you implement this keyword? :P

 Regards,
 Alexander Panek


I *do* understand them, and I also do know, that they are useful and whatnot. Still, I don't like them - they are a relict of early C times. But now we've got neat, mighty conditional loops - what do we need GOTOs for? A friend of mine once wrote such code: <code> label: doSomething( ); if ( condition ) goto label; </code> That *is* a do-while loop. <code> do { doSomething( ); } while ( condition ) </code> Effectively, those two construct are the same, but the second one is, IMO, far better readable (readable as in recognization of what a program is doing). Regards, Alexander Panek
Apr 30 2006
next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
I can also show you awful OOP.  By your logic, OOP is thereby flawed and 
should never be used.

Yet, that is not a good assertion.  Just because a goto can be used to 
do evil does not mean it is, necessarily, evil - as long as it is used 
only for good.  Just like anything else.

But obviously, this is not good and evil.  Still.

-[Unknown]


 I *do* understand them, and I also do know, that they are useful and 
 whatnot. Still, I don't like them - they are a relict of early C times. 
 But now we've got neat, mighty conditional loops - what do we need GOTOs 
 for?
 
 A friend of mine once wrote such code:
 
 <code>
 label:
 doSomething( );
 
 if ( condition )
     goto label;
 </code>
 
 That *is* a do-while loop.
 
 <code>
 do {
     doSomething( );
 } while ( condition )
 </code>
 
 Effectively, those two construct are the same, but the second one is, 
 IMO, far better readable (readable as in recognization of what a program 
 is doing).
 
 Regards,
 Alexander Panek

Apr 30 2006
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 01 May 2006 00:21:29 +0200, Alexander Panek wrote:


...

 A friend of mine once wrote such code:
 
 <code>
 label:
 doSomething( );
 
 if ( condition )
 	goto label;
 </code>
 
 That *is* a do-while loop.
 
 <code>
 do {
 	doSomething( );
 } while ( condition )
 </code>

The problem, IMHO, with this is not the 'goto' per se, but the label. The existence of a label opens the possibility that somewhere *else* in the code is a reference to that label and so as a code maintainer, I must examine all the code for such a reference. This takes time (even though it might only be a seconds using a good editor) it does add further maintenance cost. And if I do find other references, I need to examine the implications of any change I make to the local area around the label to ensure there are no unintended side-effects due to code jumping to the label ... more time used up! It is for that reason that controlled gotos such as 'do-while' are preferred to uncontrolled gotos. The 'goto' statement is not the real problem, its the label that's the issue. In fact, I'm a firm believer that if a section of code contains a 'goto'/'label' in order to improve the efficiency or legibility then it is a sign that there is a higher level construct missing in the language. Knuth has given us a few examples where 'goto' does improve the reader's knowledge of the intent of the author or removes redundantly executed code. I regard this as a failing in the language used to encode the algorithms, because the use of labels that can be reached from outside the context of the immediate section is a maintenance cost we don't need. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 1/05/2006 12:46:16 PM
Apr 30 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Derek Parnell wrote:
 
 The problem, IMHO, with this is not the 'goto' per se, but the label. 
 
 The existence of a label opens the possibility that somewhere *else* in the
 code is a reference to that label and so as a code maintainer, I must
 examine all the code for such a reference. This takes time (even though it
 might only be a seconds using a good editor) it does add further
 maintenance cost. And if I do find other references, I need to examine the
 implications of any change I make to the local area around the label to
 ensure there are no unintended side-effects due to code jumping to the
 label ... more time used up!
 

Based on some previous notion that I don't where I got it from, and from your comments, I thought /goto/ (in both D and C) could jump anywhere in the code, even across functions, but that is not so. So there isn't such label problem as you mention. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 03 2006
prev sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Mon, 01 May 2006 06:08:53 +1000, Unknown W. Brackets  
<unknown simplemachines.org> wrote:

 At the risk of asking a stupid question, what is wrong with gotos?

 I realize they can result in code that people with insufficient  
 programming experience might not understand (and I'm not trying to be  
 arrogant here, because I avoid using gotos for exactly and only this  
 reason, I don't use or read them enough.)

 But that doesn't seem reason enough for everyone to hate them.  If I see  
 a need for one, I use it - and I add comments to make sure no one gets  
 confused.

 Is the only reason that people fear them, or is there a real legitimate  
 reason?

The use of 'goto' has an inherinent cost in terms of ongoing maintenance of code. In short, it adds to the time it takes to analyse code prior to making changes that do not have unintended side-effects. That cost must be justifed. Therefore one should only use 'goto' in situation in which the cost of its use can be offset by some other gain in the code. Such a gain is performance in a performace-critical section of code. I'm not sure if there are any other situations it is cost-justified. -- Derek Parnell Melbourne, Australia
Apr 30 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Derek Parnell wrote:
 The use of 'goto' has an inherinent cost in terms of ongoing maintenance 
 of code. In short, it adds to the time it takes to analyse code prior to 
 making changes that do not have unintended side-effects. That cost must 
 be justifed. Therefore one should only use 'goto' in situation in which 
 the cost of its use can be offset by some other gain in the code. Such a 
 gain is performance in a performace-critical section of code. I'm not 
 sure if there are any other situations it is cost-justified.

A goto is also useful: 1) to avoid excessive diffs caused by refactoring code 2) when one wants to build a control structure that just doesn't fit into the usual if-else, while, for, etc. 3) to avoid the creation of silly 'flag' state variables 4) to create an efficient state machine 5) as output from program generators 6) to, for instance, collect all error handling code in one spot in a function
Apr 30 2006
next sibling parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 Derek Parnell wrote:
 
 The use of 'goto' has an inherinent cost in terms of ongoing 
 maintenance of code. In short, it adds to the time it takes to analyse 
 code prior to making changes that do not have unintended side-effects. 
 That cost must be justifed. Therefore one should only use 'goto' in 
 situation in which the cost of its use can be offset by some other 
 gain in the code. Such a gain is performance in a performace-critical 
 section of code. I'm not sure if there are any other situations it is 
 cost-justified.

A goto is also useful: 1) to avoid excessive diffs caused by refactoring code 2) when one wants to build a control structure that just doesn't fit into the usual if-else, while, for, etc. 3) to avoid the creation of silly 'flag' state variables 4) to create an efficient state machine 5) as output from program generators 6) to, for instance, collect all error handling code in one spot in a function

#4 is definately useful within a switch(){} Alternate design strategies aside, I was always told that goto, in general, lead to *less* efficient code. Didn't compilers (perhaps in the past) disable the optimizer for functions with one or more instances of goto? Doesn't it mess with flow analysis, or something?
Apr 30 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 Alternate design strategies aside, I was always told that goto, in 
 general, lead to *less* efficient code. Didn't compilers (perhaps in the 
 past) disable the optimizer for functions with one or more instances of 
 goto? Doesn't it mess with flow analysis, or something?

I don't think any compiler built since 1982 had such limitations. In fact, the way the DM optimizer works is by converting all constructs to goto's and *then* operating on it. The algorithms to do this are well known, and are even in the Dragon Book (vintage 1979). Goto's will not adversely affect optimization at all.
Apr 30 2006
parent reply kris <foo bar.com> writes:
Walter Bright wrote:
 kris wrote:
 
 Alternate design strategies aside, I was always told that goto, in 
 general, lead to *less* efficient code. Didn't compilers (perhaps in 
 the past) disable the optimizer for functions with one or more 
 instances of goto? Doesn't it mess with flow analysis, or something?

I don't think any compiler built since 1982 had such limitations. In fact, the way the DM optimizer works is by converting all constructs to goto's and *then* operating on it. The algorithms to do this are well known, and are even in the Dragon Book (vintage 1979). Goto's will not adversely affect optimization at all.

hehe ;) Obviously been a while since I looked then ... I recall MWC being like that, and also the, umm, Lattice or Aztec -- a bit foggy now. Oh well ... thanks.
Apr 30 2006
parent Walter Bright <newshound digitalmars.com> writes:
kris wrote:
 Walter Bright wrote:
 kris wrote:

 Alternate design strategies aside, I was always told that goto, in 
 general, lead to *less* efficient code. Didn't compilers (perhaps in 
 the past) disable the optimizer for functions with one or more 
 instances of goto? Doesn't it mess with flow analysis, or something?

I don't think any compiler built since 1982 had such limitations. In fact, the way the DM optimizer works is by converting all constructs to goto's and *then* operating on it. The algorithms to do this are well known, and are even in the Dragon Book (vintage 1979). Goto's will not adversely affect optimization at all.

hehe ;) Obviously been a while since I looked then ... I recall MWC being like that, and also the, umm, Lattice or Aztec -- a bit foggy now.

Those compilers, to my knowledge, never did data flow analysis or had a true optimizer in them.
May 01 2006
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Sun, 30 Apr 2006 20:06:34 -0700, Walter Bright wrote:

 Derek Parnell wrote:
 The use of 'goto' has an inherinent cost in terms of ongoing maintenance 
 of code. 


...
 I'm not sure if there are any other situations it is cost-justified.


 A goto is also useful:

Thanks Walter. I don't want to take up any of your time so feel free to ignore this response. I just want to repeat that my concern with the use of 'goto' and labels is that they add to the cost of maintaining source code. If that cost can be justified or offset by something else then fine. Otherwise just don't do it.
 1) to avoid excessive diffs caused by refactoring code

If by 'refactoring' code you mean reorganizing it so that its structure is improved then I don't see how adding 'goto' is going to achieve that. But even if it did, is the ongoing cost of cosmetic 'goto' statements worth the once-off cost of a manually review of a large diff due to lots of code movement? If it is then fine, use goto, otherwise suck it up and get on with improving the source code for future maintainers.
 2) when one wants to build a control structure that just doesn't fit 
 into the usual if-else, while, for, etc.

This is a common excuse for goto usage. But again if the special structure is justified in terms of ongoing maintenance costs then everything is just fine. However I suspect that in most cases the 'special' is not worth it. But also, this could be used as an example of a missing construct in the language and that this is emulated using uncontrolled goto statements. Such is the case with a 'retry' concept and that's why I think it would be a useful addition to D.
 3) to avoid the creation of silly 'flag' state variables

Yes. Knuth often points to this situation as a reason to use goto. The 'flag' variable is conceptually redundant and can be expensive to use at run-time. And I see this as another opportunity for a language to evolve so that such 'flags' are both avoided and the 'goto' used in their absence is also avoided. It would be *not* hard to generalize this situation so that a new syntax could be introduced to cater for it, as it is fairly common.
 4) to create an efficient state machine

Even though state machines are reasonably rare, they are very handy in some situations. Again, it would not be hard for a language to come up with a decent syntax to help people encode a state machine without uncontrolled goto statements and to help the compiler generate efficient object code. If there is specific syntax for state machines, it will reduce maintenance costs and might even help people see where they can use them rather than some other construct.
 5) as output from program generators

The output from these are not usually designed for human readers nor designed to be directly maintained. Therefore the use of goto statements has some place in this sort of output. In fact, it is metaphorically machine code.
 6) to, for instance, collect all error handling code in one spot in a 
 function

Yes, this is a very common usage for goto statements. Not so much as a performance enhancer because errors are supposed to be infrequent, but to improve source code maintainability. However, I believe that the benefit of goto usage here is lost due to the 'uncontrolled' nature of it. It introduces labels that can theoretically be reached from places other than the error handlers. In spite of that, I feel that this is a prime candidate for new syntax to deal with the problem of consolidating error handling code. It could be thought of an extension to D's 'try-catch' and 'scope' constructs, so I would encourage you to consider further evolving D into a language to delight code authors and maintainers, and also compiler writers. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 1/05/2006 2:12:33 PM
Apr 30 2006
parent James Dunne <james.jdunne gmail.com> writes:
Derek Parnell wrote:
 On Sun, 30 Apr 2006 20:06:34 -0700, Walter Bright wrote:
 [snip]
6) to, for instance, collect all error handling code in one spot in a 
function

Yes, this is a very common usage for goto statements. Not so much as a performance enhancer because errors are supposed to be infrequent, but to improve source code maintainability. However, I believe that the benefit of goto usage here is lost due to the 'uncontrolled' nature of it. It introduces labels that can theoretically be reached from places other than the error handlers. In spite of that, I feel that this is a prime candidate for new syntax to deal with the problem of consolidating error handling code. It could be thought of an extension to D's 'try-catch' and 'scope' constructs, so I would encourage you to consider further evolving D into a language to delight code authors and maintainers, and also compiler writers.

In my own language I've come up with the try/failure block in combination with the 'fail' statement. It's basically like this: try { if (conditionA) fail; if (conditionB) fail; if (conditionC) fail; success; } failure { writef("An error occurred! Cannot proceed.\n"); } -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunne
May 01 2006
prev sibling next sibling parent =?UTF-8?B?QW5kZXJzIEYgQmrDtnJrbHVuZA==?= <afb algonet.se> writes:
Walter Bright wrote:

 A goto is also useful:

 6) to, for instance, collect all error handling code in one spot in a 
 function

Apple uses this technique extensively in their "Carbon" programs (C). They just hide it away with some macros they devised back in 1992... http://www.mactech.com/articles/develop/issue_11/Parent_final.html They are still present in /usr/include/AssertMacros.h, and in Carbon. See http://developer.apple.com/carbon, and http://tinyurl.com/pk94g And yes, other higher level languages would use exceptions instead. ;) --anders
Apr 30 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Walter Bright wrote:
  > A goto is also useful:
 
 1) to avoid excessive diffs caused by refactoring code
 

I too didn't quite get this one. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 01 2006
prev sibling next sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Walter Bright wrote:
 Rick C. Hodgin wrote:
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

I know goto's are evil, but I tend to write such as: int i; for (i=0; i<10; i++) { Lretry: if (string.substr(i,1) == something) { i += some_other_function(); goto Lretry; } else if (string.substr(i,1) == something_else) { i += some_other_function2(); goto Lretry; } // Otherwise, simply execute the "i++" and re-test }

That wouldn't be the same, since for what they said, "retry" should re-test the condition (i<10), not just re-execute the block. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Apr 30 2006
prev sibling parent Rick C. Hodgin <Rick_member pathlink.com> writes:
In article <e30i88$1q4n$1 digitaldaemon.com>, Walter Bright says...
I know goto's are evil, but I tend to write such as:

int i;
for (i=0; i<10; i++)
{
   Lretry:
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         goto Lretry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         goto Lretry;
     }
     // Otherwise, simply execute the "i++" and re-test
}

The problem here is the test condition is not being executed. In theory, "i += some_other_function()" could increment i beyond the value desired in the for loop conditional-clause. The Lretry would not officially retry the test condition and could, therefore, potentially execute on values of i that are undesired by being outside the scope of the for loop, introducing a trait that a well-written program should not include. - Rick C. Hodgin
Apr 30 2006
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
I would probably do something more like (assuming there is no other code 
but the tests):

int i = 0;
while (i < 10)
{
     if (string[i] == something)
     {
         i += some_other_function();
         continue;
     }
     else if (string[i] == something_else)
     {
         i += some_other_function2();
         continue;
     }

     // Otherwise, simply execute the "i++" and re-test
     i++;
}

I mean, while is a keyword too, isn't it?  I really am unclear on how 
it's any more obtuse... perhaps you're just not as used to it?

Do you cut everything, even cheese and fruit, with a steak knife? 
Perhaps you do.  But do master chefs as well?  Or do they use the right 
knives for the right purposes?

Actually, I might do this depending on the number of tests:

int pos = 0;
while (pos < string.length)
{
     switch (string[pos])
     {
     case something:
         pos += some_other_function(string[pos .. string.length]);
         break;

     case something_else:
         pos += some_other_function2(string[pos .. string.length]);
         break;

     default:
         pos++;
     }
}

Which, to me, seems much more clear than any "retry" would.  In fact, 
"retry" would seem incredibly unclear to me.  That's just me.  I don't 
see the concept of "retrying" anywhere.

The above code looks somewhat similar to code I've used in an xml 
document parser and a simple abbreviated xpath expression evaluator.  I 
can't even remember the last time I've used/wanted anything like a "retry".

Clearly, just my opinion.

-[Unknown]


 Here's an idea:
 
 There should be a way in D to allow the reconsideration of a for..loop test
 clause without executing the increment clause.
 
 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)
 
 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }
 
 I propose the name "retry" for the "retest without increment-clause" command,
to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to the
 conditional-clause code section, thereby allowing subsequent passes through the
 for loop without the requisite and occasionally unnecessary
auto-incrementation.
 
 It would just be a way to give for loops a little more natural utility without
 having to do some rather obtuse programming techniques, such as using goto's or
 enclosing the code in a while or do loop, etc.
 
 - Rick C. Hodgin
 
 
 
 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }

Apr 29 2006
next sibling parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Unknown W. Brackets wrote:
 I would probably do something more like (assuming there is no other code 
 but the tests):
 
 int i = 0;
 while (i < 10)
 {
     if (string[i] == something)
     {
         i += some_other_function();
         continue;
     }
     else if (string[i] == something_else)
     {
         i += some_other_function2();
         continue;
     }
 
     // Otherwise, simply execute the "i++" and re-test
     i++;
 }
 
 I mean, while is a keyword too, isn't it?  I really am unclear on how 
 it's any more obtuse... perhaps you're just not as used to it?
 
 Do you cut everything, even cheese and fruit, with a steak knife? 
 Perhaps you do.  But do master chefs as well?  Or do they use the right 
 knives for the right purposes?
 
 Actually, I might do this depending on the number of tests:
 
 int pos = 0;
 while (pos < string.length)
 {
     switch (string[pos])
     {
     case something:
         pos += some_other_function(string[pos .. string.length]);
         break;
 
     case something_else:
         pos += some_other_function2(string[pos .. string.length]);
         break;
 
     default:
         pos++;
     }
 }
 
 Which, to me, seems much more clear than any "retry" would.  In fact, 
 "retry" would seem incredibly unclear to me.  That's just me.  I don't 
 see the concept of "retrying" anywhere.
 
 The above code looks somewhat similar to code I've used in an xml 
 document parser and a simple abbreviated xpath expression evaluator.  I 
 can't even remember the last time I've used/wanted anything like a "retry".
 
 Clearly, just my opinion.
 
 -[Unknown]
 
 
 Here's an idea:

 There should be a way in D to allow the reconsideration of a for..loop 
 test
 clause without executing the increment clause.

 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)

 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }

 I propose the name "retry" for the "retest without increment-clause" 
 command, to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight 
 to the
 conditional-clause code section, thereby allowing subsequent passes 
 through the
 for loop without the requisite and occasionally unnecessary 
 auto-incrementation.

 It would just be a way to give for loops a little more natural utility 
 without
 having to do some rather obtuse programming techniques, such as using 
 goto's or
 enclosing the code in a while or do loop, etc.

 - Rick C. Hodgin



 int i;
 for (i=0; i<10; i++)
 {
     if (string.substr(i,1) == something)
     {
         i += some_other_function();
         retry;
     }
     else if (string.substr(i,1) == something_else)
     {
         i += some_other_function2();
         retry;
     }
     // Otherwise, simply execute the "i++" and re-test
 }


This, to me, is the right solution to the design pattern. No need for a new keyword, and the functionality is clearly the same.
Apr 29 2006
parent reply kellywilson nowhere.com writes:
Hello all,

I agree with Kyle on this one as well. I have added the "retry" keyword to my
parser and it really amounts to the same thing as "continue". The only
difference would be if one were to restrict the "retry" keyword to work only
within the 'for' and 'foreach' loop constructs. This is a little tough to do
with the grammar (though it can be done in the semantic checking phase fairly
easily, I believe....Walter [or someone very familiar with the dmdfe] may have
to answer that one since my parser doesn't do semantic checking yet ;)

Anyways, easy to add keyword, but in the same place as "continue", so why do it?

My two cents,
Kelly Wilson 

In article <e31khr$6tg$1 digitaldaemon.com>, Kyle Furlong says...
Unknown W. Brackets wrote:
 I would probably do something more like (assuming there is no other code 
 but the tests):
 
 int i = 0;
 while (i < 10)
 {
     if (string[i] == something)
     {
         i += some_other_function();
         continue;
     }
     else if (string[i] == something_else)
     {
         i += some_other_function2();
         continue;
     }
 
     // Otherwise, simply execute the "i++" and re-test
     i++;
 }
 
 I mean, while is a keyword too, isn't it?  I really am unclear on how 
 it's any more obtuse... perhaps you're just not as used to it?
 
 Do you cut everything, even cheese and fruit, with a steak knife? 
 Perhaps you do.  But do master chefs as well?  Or do they use the right 
 knives for the right purposes?
 
 Actually, I might do this depending on the number of tests:
 
 int pos = 0;
 while (pos < string.length)
 {
     switch (string[pos])
     {
     case something:
         pos += some_other_function(string[pos .. string.length]);
         break;
 
     case something_else:
         pos += some_other_function2(string[pos .. string.length]);
         break;
 
     default:
         pos++;
     }
 }
 
 Which, to me, seems much more clear than any "retry" would.  In fact, 
 "retry" would seem incredibly unclear to me.  That's just me.  I don't 
 see the concept of "retrying" anywhere.
 
 The above code looks somewhat similar to code I've used in an xml 
 document parser and a simple abbreviated xpath expression evaluator.  I 
 can't even remember the last time I've used/wanted anything like a "retry".
 
 Clearly, just my opinion.
 
 -[Unknown]
 
 

This, to me, is the right solution to the design pattern. No need for a new keyword, and the functionality is clearly the same.

Apr 30 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sun, 30 Apr 2006 20:34:09 +1000, <kellywilson nowhere.com> wrote:


 Anyways, easy to add keyword, but in the same place as "continue", so  
 why do it?

Because 'continue' and 'retry' are not the same thing. 'continue' means go to the next iteration, and 'retry' means repeat the same iteration. ....CONCEPTUAL CODE.... for_start: init_code; for_test: if ( end_condition ) goto for_end; for_body: do_something; if <A> goto for_index; // continue if <B> goto for_test; // retry if <C> goto for_start; // restart if <D> goto for_end; // break; for_index: update_index; goto for_test; for_end: -- Derek Parnell Melbourne, Australia
Apr 30 2006
next sibling parent reply kellywilson nowhere.com writes:
Thanks Derek,

I see your point, I was just sort of going off of Kyle's quote "and the
functionality is clearly the same" without realising he meant the overall
functionality, and not the keywords (oops). I was also looking at the while loop
example code and it seemed that the two would be the same (just for that
construct though, I see). However, since we can just write the code with a
different construct and/or 'goto's, then should we use extra keywords and make
the language even bigger? Maybe you are suggesting that it would be easier to
just let the compiler add in the correct jumps instead of making the user add in
explicit 'goto's and possibly use a different construct? 

I think the new keyword (or words if we include 'restart' as well) may lead to
some nasty little logic bugs for new users, if they aren't careful, though. I
know that can be said about many 'new' keywords/features for newer languages,
but still, in this case it may be troublesome for those moving from C/C++.
Maybe? Thoughts?

Thanks,
Kelly Wilson

P.S. Your example does rather pointedly show that this can all be solved easily
with some 'goto's as Walter showed/suggested earlier ;) One argument for goto's
follows:  http://www.ppig.org/papers/12th-marshall.pdf
or here:  http://www.stevemcconnell.com/ccgoto.htm


In article <op.s8tl32d56b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
On Sun, 30 Apr 2006 20:34:09 +1000, <kellywilson nowhere.com> wrote:


 Anyways, easy to add keyword, but in the same place as "continue", so  
 why do it?

Because 'continue' and 'retry' are not the same thing. 'continue' means go to the next iteration, and 'retry' means repeat the same iteration. ....CONCEPTUAL CODE.... for_start: init_code; for_test: if ( end_condition ) goto for_end; for_body: do_something; if <A> goto for_index; // continue if <B> goto for_test; // retry if <C> goto for_start; // restart if <D> goto for_end; // break; for_index: update_index; goto for_test; for_end: -- Derek Parnell Melbourne, Australia

Apr 30 2006
parent "Derek Parnell" <derek psych.ward> writes:
On Mon, 01 May 2006 05:28:17 +1000, <kellywilson nowhere.com> wrote:


 However, since we can just write the code with a
 different construct and/or 'goto's, then should we use extra keywords  
 and make
 the language even bigger?

If one takes this argument, we should remove constructs such as 'for', 'foreach', 'switch', 'while' etc...
 Maybe you are suggesting that it would be easier to
 just let the compiler add in the correct jumps instead of making the  
 user add in
 explicit 'goto's and possibly use a different construct?

Yes. Source code is supposed to be primarily designed for humans to read and thus we need to help humans understand the intent of the code and leave the compiler to correctly translate it for the machines.
 I think the new keyword (or words if we include 'restart' as well) may  
 lead to
 some nasty little logic bugs for new users, if they aren't careful,  
 though. I
 know that can be said about many 'new' keywords/features for newer  
 languages,
 but still, in this case it may be troublesome for those moving from  
 C/C++.
 Maybe? Thoughts?

So what! Let them learn D instead.
 P.S. Your example does rather pointedly show that this can all be solved  
 easily
 with some 'goto's as Walter showed/suggested earlier ;) One argument for  
 goto's
 follows:  http://www.ppig.org/papers/12th-marshall.pdf
 or here:  http://www.stevemcconnell.com/ccgoto.htm

My take on goto is that its usage is justified when there is no other way to add performace to a demonstably performance critical section of code. In other words, the 'cost' of using goto must be offset by some other gain. -- Derek Parnell Melbourne, Australia
Apr 30 2006
prev sibling parent Rick C. Hodgin <Rick_member pathlink.com> writes:
In article <op.s8tl32d56b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...
 Anyways, easy to add keyword, but in the same place as "continue", so  
 why do it?

Because 'continue' and 'retry' are not the same thing. 'continue' means go to the next iteration, and 'retry' means repeat the same iteration. ....CONCEPTUAL CODE.... for_start: init_code; for_test: if ( end_condition ) goto for_end; for_body: do_something; if <A> goto for_index; // continue if <B> goto for_test; // retry if <C> goto for_start; // restart if <D> goto for_end; // break; for_index: update_index; goto for_test; for_end:

Derek, you nailed it here. These should be the exact keywords used for this concept, because these are the sum total of mechanisms which could be applied. And they have the added benefit of accomplishing the same things that can be accomplished in other ways, but in a more straight-forward and elegent manner. I applaud your contribution. One other potentially desirable condition that I could've used a few times is this:
....CONCEPTUAL CODE....

    for_start:
        init_code;
    for_test:
        if ( end_condition ) goto for_end;
    for_body:
        do_something;
        if <A> goto for_index; // continue
        if <B> goto for_test; // retry
        if <C> goto for_start; // restart
        if <D> goto for_end; // break;
        if <E> goto for_invalidate_end; // ibreak
    for_index:
        update_index;
        goto for_test;
    for_invalidate_end:
        set test value to some value indicating hard break
    for_end:

I propose the actual syntax for this invalidate-break to be: for (i=0; i<10; i++) { // Code goes here for loop } (i = -1); With the invalidated value being specified at the end of the for loop as the "(i = -1)" code. This would allow instances where the for loop was exited through a hard ibreak command to set the value to some identifiable condition in an elegant manner. I further propose that the block of code contained there could also be either a series of semicolon delimited commands (which would execute multiple instructions) or a block of code enclosed by braces within the trailing parenthesis, as in: for (i=0; i<10; i++) { // Code goes here for loop } ({ // Invalidation code would go here }); These are some thoughts I've had to make the elegence of the programming concepts more straight- forward, to be supported by the compiler, and to remove the need for certain types of work-arounds right now for (perhaps even not so common) bits of code (but rather code that needs to work in this way, and to do so in a straight-forward manner). - Rick C. Hodgin
Apr 30 2006
prev sibling parent reply James Dunne <james.jdunne gmail.com> writes:
Unknown W. Brackets wrote:
 [snip]
 
 int pos = 0;
 while (pos < string.length)
 {
     switch (string[pos])
     {
     case something:
         pos += some_other_function(string[pos .. string.length]);
         break;
 
     case something_else:
         pos += some_other_function2(string[pos .. string.length]);
         break;
 
     default:
         pos++;
     }
 }
 

Does anyone else see the inconsistency with the break and continue keywords as applied to switch statements within loop constructs? switch uses break to leave the switch statement, while continue is still used in the loop context. I think this should be fixed so that exit leaves the switch statement and break and continue are left for the loop. -- Regards, James Dunne
Apr 30 2006
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
I think this is why labeling for these constructs was introduced.

-[Unknown]


 Does anyone else see the inconsistency with the break and continue 
 keywords as applied to switch statements within loop constructs?
 
 switch uses break to leave the switch statement, while continue is still 
 used in the loop context.  I think this should be fixed so that exit 
 leaves the switch statement and break and continue are left for the loop.
 

Apr 30 2006
prev sibling next sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Very neat idea.
Several times I've run into situations where this construct would've 
been very helpful.

Gets my vote!

Rick C. Hodgin wrote:
 Here's an idea:
 
 There should be a way in D to allow the reconsideration of a for..loop test
 clause without executing the increment clause.
 
 Using the terminology:
 for (initialize-clause; conditional-clause; increment-clause)
 
 Example:
 int i;
 for (i=0; i<10; i++)
 {
 if (string.substr(i,1) == something)
 {
 i += some_other_function();
 retry;
 }
 else if (string.substr(i,1) == something_else)
 {
 i += some_other_function2();
 retry;
 }
 // Otherwise, simply execute the "i++" and re-test
 }
 
 I propose the name "retry" for the "retest without increment-clause" command,
to
 be used in a manner similar syntax-wise to the way "break" is used today.
 "Retry" would simply bypass the increment-clause and proceed straight to the
 conditional-clause code section, thereby allowing subsequent passes through the
 for loop without the requisite and occasionally unnecessary
auto-incrementation.
 
 It would just be a way to give for loops a little more natural utility without
 having to do some rather obtuse programming techniques, such as using goto's or
 enclosing the code in a while or do loop, etc.
 
 - Rick C. Hodgin
 
 

Apr 29 2006
prev sibling next sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
I'm all for the addition of 'retry' statement for all loops (while, for,
foreach).  In 
fact, I think it would even be nifty in switch statements:

# switch (something) {
#   case foo:
#     doStuff();
#     break;
#
#   case bar:
#     doOtherStuff();
#     break;
#
#   default:
#     something = doAnotherThing();
#     retry;
# }

The 'restart' statement I'm not entirely convinced about, though.  For two
reasons. 
Reason one, its just too common/likely a name for variables/fields &
functions/methods. 
Who hasn't written a class with a .restart() method before?

Reason two:

# { bool _sentinel; do { _sentinel = false;
#   foreach (i, x; some_collection) {
#     /*...do stuff...*/
#     if (/*...some condition...*/) {
#       _sentinel = true;
#       break;
#     }
#   }
# } while (_sentinel); }

Not particularly pretty, no, but it gets the job done and (IMHO) reads decently
enough. 
If 'restart' adds some optimization ability this convention does not, then
fine, so be 
it... just, can we please find another name, because Reason One is the big one
to me.

-- Chris Nicholson-Sauls
May 03 2006
prev sibling parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Rick C. Hodgin wrote:
 Here's an idea:
 

I really like the idea of repeat and restart because (like Derek nicely explained) these two are simply the ones that are missing. There is no more reason to have break and continue than to have repeat and restart because all these four really are is fancy gotos. This feature is one of those that new users will instantly recognize as "wow I could have used this many times if it was in my old xyz language"
May 09 2006