Thread overview
Proposal: for/then/else statement
Jan 03, 2013
Linden Krouse
Jan 03, 2013
Tobias Pankrath
Jan 03, 2013
qznc
Jan 03, 2013
Linden Krouse
Jan 03, 2013
Tobias Pankrath
Jan 03, 2013
bearophile
Jan 03, 2013
deed
Jan 03, 2013
deed
Jan 03, 2013
Timon Gehr
Jan 03, 2013
Nick Sabalausky
January 03, 2013
My proposal is for a slight addition to for and foreach statements by allowing different blocks of code to be executed whether the loop is exited from the condition failing or a break statement. These would of course be independently optional.
For example:

for(int num = 0; num < 10; num++)
{
    if(<condition>)
        break;
}
then
{
    //num successfully counted up to 10
    //do stuff...
}
else
{
    //loop was broken prematurely
    //do other stuff...
}

One instance where this would be useful is in situations when code should be executed if an item is not found while searching.
For example:

Current solution:

int[] nums = [1, 2, 3, 4, 5];
int i = 6;

bool intFound = false;
foreach(n; nums)
{
    if(n == i)
    {
        intFound = true;
        break;
    }
}

if(!intFound)
{
    //i was not found, do stuff
}

Using for/then/else:

int[] nums = [1, 2, 3, 4, 5];
int i = 6;

foreach(n; nums)
{
    if(n == i)
        break;
}
then
{
    //i was not found, do stuff
}

Not only would this be more compact and easier to read, but it should also be more efficient (less checking and less memory usage).
January 03, 2013
On Thursday, 3 January 2013 at 09:00:00 UTC, Linden Krouse wrote:
> Current solution:
>
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
>
> bool intFound = false;
> foreach(n; nums)
> {
>     if(n == i)
>     {
>         intFound = true;
>         break;
>     }
> }
>
> if(!intFound)
> {
>     //i was not found, do stuff
> }
>
> Using for/then/else:
>
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
>
> foreach(n; nums)
> {
>     if(n == i)
>         break;
> }
> then
> {
>     //i was not found, do stuff
> }
>
> Not only would this be more compact and easier to read, but it should also be more efficient (less checking and less memory usage).

Python has a very similar thing, where you can have an else after a loop. However I always found it unintuitive whether the else branch gets executed if you break the loop or if you finish all iterations without breaking. Even now I'd have to look it up.
January 03, 2013
On Thursday, 3 January 2013 at 09:00:00 UTC, Linden Krouse wrote:
> My proposal is for a slight addition to for and foreach statements by allowing different blocks of code to be executed whether the loop is exited from the condition failing or a break statement. These would of course be independently optional.

Interesting. I was thinking about such a language feature myself for some time.

Just a small extension to your proposal: It also applies to while-loop.
January 03, 2013
> Python has a very similar thing, where you can have an else after a loop. However I always found it unintuitive whether the else branch gets executed if you break the loop or if you finish all iterations without breaking. Even now I'd have to look it up.

"then" and "else could be changed to something more descriptive, they were just the first keywords that came to mind.
January 03, 2013
On Thursday, 3 January 2013 at 09:51:59 UTC, Linden Krouse wrote:
>> Python has a very similar thing, where you can have an else after a loop. However I always found it unintuitive whether the else branch gets executed if you break the loop or if you finish all iterations without breaking. Even now I'd have to look it up.
>
> "then" and "else could be changed to something more descriptive, they were just the first keywords that came to mind.

I don't think any new keywords will make it into the language.
January 03, 2013
Linden Krouse:

> "then" and "else could be changed to something more descriptive, they were just the first keywords that came to mind.

I find the "else" of "for" sometimes handy in Python, but using "else" for "unbroken" is not good enough. A more descriptive keyword is kind of needed here. But I don't think Walter wants to add new keywords to D now.

Bye,
bearophile
January 03, 2013
> for(int num = 0; num < 10; num++)
> {
>     if(<condition>)
>         break;
> }
> then
> {
>     //num successfully counted up to 10
>     //do stuff...
> }
> else
> {
>     //loop was broken prematurely
>     //do other stuff...
> }


How about using scope inside the loop?

for (int num = 0; num < 10; num++)
{
    // do stuff...

    if (<condition>)
        break;

    scope(loop_break)
    {
        // loop was broken prematurely
        // do other stuff...
    }

    scope(loop_finish)
    {
        //  num successfully counted up to 10
        //  do stuff...
    }
}
January 03, 2013
More descriptive:

scope(loop_interrupted)
scope(loop_completed)
January 03, 2013
On Thursday, 3 January 2013 at 09:00:00 UTC, Linden Krouse wrote:
> ...
>
> Current solution:
>
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
>
> bool intFound = false;
> foreach(n; nums)
> {
>     if(n == i)
>     {
>         intFound = true;
>         break;
>     }
> }
>
> if(!intFound)
> {
>     //i was not found, do stuff
> }
>
> Using for/then/else:
>
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
>
> foreach(n; nums)
> {
>     if(n == i)
>         break;
> }
> then
> {
>     //i was not found, do stuff
> }
>
> Not only would this be more compact and easier to read, but it should also be more efficient (less checking and less memory usage).

Current solution:

foreach(n;nums) if(n==i) goto Lfound;
// i was not found, do stuff
Lfound:;

I think that any more or less decent compiler back end ought to be able to transform your boolean flag code into this form. (If the foreach loop is executed sufficiently many times, it does not make any kind of meaningful difference anyways.) This proposal is about convenient syntax.
January 03, 2013
On Thu, 03 Jan 2013 09:59:59 +0100
"Linden Krouse" <ztaticnull@gmai.com> wrote:

> My proposal is for a slight addition to for and foreach
> statements by allowing different blocks of code to be executed
> whether the loop is exited from the condition failing or a break
> statement. These would of course be independently optional.
> For example:
> 
> for(int num = 0; num < 10; num++)
> {
>      if(<condition>)
>          break;
> }
> then
> {
>      //num successfully counted up to 10
>      //do stuff...
> }
> else
> {
>      //loop was broken prematurely
>      //do other stuff...
> }
> 
> One instance where this would be useful is in situations when code should be executed if an item is not found while searching. For example:
> 
> Current solution:
> 
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
> 
> bool intFound = false;
> foreach(n; nums)
> {
>      if(n == i)
>      {
>          intFound = true;
>          break;
>      }
> }
> 
> if(!intFound)
> {
>      //i was not found, do stuff
> }
> 
> Using for/then/else:
> 
> int[] nums = [1, 2, 3, 4, 5];
> int i = 6;
> 
> foreach(n; nums)
> {
>      if(n == i)
>          break;
> }
> then
> {
>      //i was not found, do stuff
> }
> 
> Not only would this be more compact and easier to read, but it should also be more efficient (less checking and less memory usage).

Yea, I've occasionally found myself wishing we had those.