Thread overview
Breaking out of multiple loops
Sep 05, 2012
Michel Colman
Sep 05, 2012
Piotr Szturmaj
Sep 05, 2012
monarch_dodra
Sep 05, 2012
Piotr Szturmaj
Sep 05, 2012
Regan Heath
Sep 05, 2012
monarch_dodra
Sep 05, 2012
monarch_dodra
Sep 05, 2012
monarch_dodra
Sep 05, 2012
ixid
September 05, 2012
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?

September 05, 2012
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."
September 05, 2012
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...
September 05, 2012
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 :)
September 05, 2012
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/
September 05, 2012
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?)
September 05, 2012
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
September 05, 2012
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/
September 05, 2012
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 ...
September 05, 2012
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.