www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Breaking out of multiple loops

reply "Michel Colman" <michelcolman mac.com> writes:
I have a very simple suggestion for breaking out of nested loops.

Currently, there are a few ways of breaking out of multiple 
nested loops but they all have unnecessary drawbacks:
- exceptions (performance penalty, complexity)
- using boolean flags that are checked in every iteration 
(performance hit)
- goto (ugly, generally frowned apon, although this is often 
cited as one of the few cases where using goto is actually 
acceptable, which says a lot about the lack of other options)

I propose an extremely simple solution that is probably very easy 
to implement in compilers:

break break; // breaks out of two loops
break break break; // breaks out of three loops
break break continue; // jumps to the end of the third enclosing 
loop

You might also introduce a shorthand version for breaking out of 
a whole lot of loops:
break 5; // breaks out of 5 loops

And, why not,
break 5 continue; // jumps to the end of the sixth enclosing loop

What do you think?
Sep 05 2012
next sibling parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
Sep 05 2012
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 5 September 2012 at 12:43:26 UTC, Piotr Szturmaj 
wrote:
 Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested 
 loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
I really wish there was a simple "break from current scope" command. It would be kinda like "goto end of scope", just cleaner...
Sep 05 2012
next sibling parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
monarch_dodra wrote:
 On Wednesday, 5 September 2012 at 12:43:26 UTC, Piotr Szturmaj wrote:
 Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
I really wish there was a simple "break from current scope" command. It would be kinda like "goto end of scope", just cleaner...
break scope [Identifier]; Uses two known keywords and (IMHO) looks good. Just file a feature request and wait :)
Sep 05 2012
prev sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 05 Sep 2012 13:55:32 +0100, monarch_dodra <monarchdodra gmail.com>  
wrote:

 On Wednesday, 5 September 2012 at 12:43:26 UTC, Piotr Szturmaj wrote:
 Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
I really wish there was a simple "break from current scope" command. It would be kinda like "goto end of scope", just cleaner...
You can lodge an enhancement request, example code: void main() { label: { // ..code.. writefln("code1"); writefln("break.."); break label; // jumps to "here:" // ..code.. writefln("code2"); } // break lands here writefln("here"); } Current error: test.d(nn): Error: enclosing label 'label' for break not found In fact, as any BlockStatement can be labeled you can argue any BlockStatement label should be 'breakable'. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 05 2012
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 5 September 2012 at 13:13:14 UTC, Regan Heath wrote:
 You can lodge an enhancement request, example code:

 [SNIP]

 R
Good idea actually. http://d.puremagic.com/issues/post_bug.cgi posted as enhancement request for DMD (this is correct, right?)
Sep 05 2012
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 5 September 2012 at 13:36:48 UTC, monarch_dodra 
wrote:
 On Wednesday, 5 September 2012 at 13:13:14 UTC, Regan Heath 
 wrote:
 You can lodge an enhancement request, example code:

 [SNIP]

 R
Good idea actually. http://d.puremagic.com/issues/post_bug.cgi posted as enhancement request for DMD (this is correct, right?)
Yeah.. Don't click that link... THIS is the correct link: http://d.puremagic.com/issues/show_bug.cgi?id=8622
Sep 05 2012
prev sibling parent reply Jose Armando Garcia <jsancio gmail.com> writes:
On Sep 5, 2012, at 6:13, "Regan Heath" <regan netmail.co.nz> wrote:

 On Wed, 05 Sep 2012 13:55:32 +0100, monarch_dodra <monarchdodra gmail.com 
 wrote:
 On Wednesday, 5 September 2012 at 12:43:26 UTC, Piotr Szturmaj wrote:
 Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
I really wish there was a simple "break from current scope" command. It would be kinda like "goto end of scope", just cleaner...
You can lodge an enhancement request, example code: void main() { label: { // ..code.. writefln("code1"); writefln("break.."); break label; // jumps to "here:" // ..code.. writefln("code2"); } // break lands here writefln("here"); } Current error: test.d(nn): Error: enclosing label 'label' for break not found In fact, as any BlockStatement can be labeled you can argue any BlockStatement label should be 'breakable'.
Haven't tried it but this maybe implementable using templates, try and catch. I say this because Scala, being a "functional" language implements this as a library using closure, high order function, try, catch and throw. Maybe a few other features. -jose
 R

 -- 
 Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 05 2012
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 5 September 2012 at 15:12:11 UTC, Jose Armando 
Garcia wrote:
 On Sep 5, 2012, at 6:13, "Regan Heath" <regan netmail.co.nz> 
 wrote:

 On Wed, 05 Sep 2012 13:55:32 +0100, monarch_dodra 
 <monarchdodra gmail.com
 wrote:
 On Wednesday, 5 September 2012 at 12:43:26 UTC, Piotr 
 Szturmaj wrote:
 Michel Colman wrote:
 I have a very simple suggestion for breaking out of nested 
 loops.
I think it's already there: http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
I really wish there was a simple "break from current scope" command. It would be kinda like "goto end of scope", just cleaner...
You can lodge an enhancement request, example code: void main() { label: { // ..code.. writefln("code1"); writefln("break.."); break label; // jumps to "here:" // ..code.. writefln("code2"); } // break lands here writefln("here"); } Current error: test.d(nn): Error: enclosing label 'label' for break not found In fact, as any BlockStatement can be labeled you can argue any BlockStatement label should be 'breakable'.
Haven't tried it but this maybe implementable using templates, try and catch. I say this because Scala, being a "functional" language implements this as a library using closure, high order function, try, catch and throw. Maybe a few other features. -jose
 R

 --
 Using Opera's revolutionary email client: 
 http://www.opera.com/mail/
It is implementable with a simple "label: do{}while(false);" actually. ... Or a goto ...
Sep 05 2012
prev sibling parent "ixid" <nuaccount gmail.com> writes:
A goto is actually better than "break 3" because you can modify 
inner loops and the goto will still take you to the right place, 
the "break 3" would take you to the wrong place if you change the 
number of loops. There's nothing wrong with goto in this context 
and as others have said we already have break label and continue 
label which either break or continue the labelled loop.
Sep 05 2012