Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

block-break-value #2430

Closed
SoniEx2 opened this issue May 3, 2018 · 6 comments
Closed

block-break-value #2430

SoniEx2 opened this issue May 3, 2018 · 6 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@SoniEx2
Copy link

SoniEx2 commented May 3, 2018

We have:

loop {
    break value;
}

'label: loop {
    break 'label value;
}

'label: {
    break 'label value;
}

It would be nice to extend this to other blocks:

'label: if cond {
    break 'label value;
} else {
    break 'label value;
}

'label: if let pat = expr {
    break 'label value;
} else {
    break 'label value;
}

'label: match expr {
    pat => {},
}

'label: try {
    break 'label value;
}

As opposed to:

'label: {
    if cond {
        break 'label value;
    } else {
        break 'label value;
    }
}

'label: {
    if let pat = expr {
        break 'label value;
    } else {
        break 'label value;
    }
}

'label: {
    match expr {
        pat => {},
    }
}

'label: {
    try {
        break 'label value;
    }
}

This avoids a whole level of indentation and an unnecessary pair of {}.

Note that while let and while wouldn't be changed because those can't return values.


(Note that IDEs/rustfmt are unable to cope with:

'label: { if cond {
    break 'label value;
} }

Instead, they rewrite it to:

'label: {
    if cond {
        break 'label value;
    }
}

)

@Centril
Copy link
Contributor

Centril commented May 3, 2018

cc #2046, @ciphergoth

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label May 3, 2018
@joshtriplett
Copy link
Member

Do you have a specific use case for this? (I'm not asking for hypotheses on how this could be used; do you have something specific you want to use this for?)

Much of the motivation for introducing labeled break was for macro authors, and the extra level of indentation doesn't really matter there. And the ability to break from multiple branches of an if, for instance, seems like it will increase the tendency to produce spaghetti code with non-obvious control flow.

@SoniEx2
Copy link
Author

SoniEx2 commented May 3, 2018

Mainly combining 'label and try, to avoid nesting.

See:

// as part of a very complex function, like a game loop
let x = try {
    if self.ready {
        let a = do_complex_thing?;
        more_complex_things(a)
    } else {
        Err(NotReady)
    }
}

// Vs:

let x = 'label: try {
    if !self.ready {
        break 'label Err(NotReady);
    }
    // avoids nesting
    let a = do_complex_thing?;
    more_complex_things(a)
}

(I find the latter much more readable, as the "normal" case is at the bottom of the block, not nested, and the "exceptional" case is out of the way. and yes I know about "omg please split your functions" but uh... no?)

@Centril
Copy link
Contributor

Centril commented May 4, 2018

Or just using throw (cc #2426):

let x = try {
    if !self.ready { throw NotReady; }
    let a = do_complex_thing?;
    more_complex_things(a)
}

@scottmcm
Copy link
Member

scottmcm commented May 4, 2018

I'm glad label-break-value was accepted, but hope it's only rarely seen outside of macros offering interesting control flow constructs. I see it and loop as the very bottom level of intraprocedural control flow constructs -- while, for, loop-break, continue, return, etc are all just sugar for some combination of those two.

Any time LBV is actually used the control flow is already unusual, so I actually appreciate the explicitness that comes from having a dedicated {} pair just for the label scope. It avoids confusion like "is it doing 'label: try { or try 'label: { or can I do 'foo: try 'bar?". I definitely never want to see the last of those, nor something like else 'label: {.

@Centril
Copy link
Contributor

Centril commented May 18, 2018

Closing since this doesn't seem to be going anywhere. If you want to continue with this proposal, please open a topic on internals.rust-lang.org, or write up a formal RFC proposal.

@Centril Centril closed this as completed May 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

4 participants