Idea: continue-to-else


#1

I’m imagining this syntax sugar: allow using labelled-continue within if when else if labelled.

if xxxx {
     if yyy {
       //do something
     } else {
        continue 'fallback;
     }
}
'fallback: else {
    //do something
}

Just an idea. Wonder if people think this would be useful?


#2

This seems too much like goto, so I don’t like it.


edit:
I should clarify, this is too much like unstructured goto


#3

It’s probably more straightforward just to move the computation of yyy earlier so you can include it with the if xxxx.


#4

Rust has three keywords for structured goto (return, break, and continue), so just being like goto isn’t enough on its own. The question is whether it’s the one “good” kind of goto that we already have (https://github.com/rust-lang/rfcs/pull/2046#issuecomment-311230800).

This is, however, not that good kind of goto. It’s going into a sibling block, not leaving a block it’s already in.

So you probably want to use

And rewrite it something like this:

'whole: {
    if xxxx {
        if yyy {
            //do something
            break 'whole;
        }
    }

    //do something
}

#5

The simple question is: why would you want this? I mean, genuinely… you can imagine arbitrarily complex primitives for control flow that would exactly fit some very specific use-case in some concocted situation. That’s not a good approach to language design, though.

In particular, your code, which looks like this, with a bit more descriptive labels:

if outer_condition {
     if inner_condition {
       do_something();
     } else {
        continue 'fallback;
     }
}
'fallback: else {
    do_something_else();
}

can be trivially rewritten as:

if outer_condition && inner_condition {
    do_something();
} else if !outer_condition || outer_condition && !inner_condition {
    do_something_else();
}

which in turn is just the same as

if outer_condition && inner_condition {
    do_something();
} else {
    do_something_else();
}

I fail to see how the proposed syntax could have any advantage: it merely makes interpreting control flow more difficult without adding any new functionality.


#6

I think it’s fair to assume the real case is slightly more complicated, such that it’s not as obvious. For example, tweak it slightly to

if outer_condition {
    let x = expensive();
    if inner_condition(&x) {
        do_something(x);
    } else {
        continue 'fallback;
    }
}
'fallback: else {
    do_something_else();
}

which doesn’t translate to a “trivial” if-else, but does work cleanly with LBV:

'whole: {
    if outer_condition {
        let x = expensive();
        if inner_condition(&x) {
            do_something(x);
            break 'whole;
        }
    }
    
    do_something_else();
}

EDIT: I feel like the post below this completely missed my point – I could copy-paste the same “I don’t care about any particular concrete example; you can make it slightly more complete and that rewrite doesn’t work” reply to it – but I’ll let the thread die by not making a new reply for that.


#7

With help from RFC 2497, you could write that as:

if outer_condition
    && let x = expensive()
    && inner_condition(&x) {
        do_something(x);
} else {
    do_something_else();
}

#8

Ok, i’m persuaded. Thank you everybody :slight_smile:


#9

What about:

if outer_condition && {
    let x = expensive();
    if inner_condition(&x) {
        do_something(x);
        true
    } else { false }
}
{}
else {
    do_something_else()
}

EDIT: or even shorter (but maybe less readable)

if !(outer_condition && {
    let x = expensive();
    inner_condition(&x) && {
        do_something(x);
        true
    }
})
{
    do_something_else()
}

#10

That would also work


closed #11

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.