Skip to content

Turn return/continue/break/rethrow statements into expressions? #2099

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

Closed
eernstg opened this issue Feb 7, 2022 · 1 comment
Closed

Turn return/continue/break/rethrow statements into expressions? #2099

eernstg opened this issue Feb 7, 2022 · 1 comment
Labels
feature Proposed language feature that solves one or more problems

Comments

@eernstg
Copy link
Member

eernstg commented Feb 7, 2022

[Edit: Closed this as a duplicate of #2025.]

We have requests now and then for introducing an immediate and non-normal completion of an expression evaluation.

We already have the ability to abruptly terminate an ongoing expression evaluation using throw e, but in some situations it can be convenient to complete the expression evaluation 'returning' rather than 'throwing', or 'continuing', or 'breaking', and it is not optimal from a performance or code readability point of view to throw something and then break, continue, return from a catch or finally block, and this kind of workaround will not work with rethrow.

So we could introduce <returnExpression>, <breakExpression>, <continueExpression>, <rethrowExpression>, and allow them to occur as expressions of type Never, with the same syntactic precedence as <throwExpression>. The semantics would be to immediately terminate the evaluation of the enclosing expression, and then give rise to the same data transfer and control transfer as the corresponding <returnStatement> etc. do today.

An issue where a similar request has been put forward is #2095, where it is requested that e ?? return can be used as an expression, and #2088 is a similar proposal.

#2025 is very similar to this issue; it mentions both continue and break as well as return, and proposes the type Never for these expressions. It may or may not assume that the new expressions can only occur as the second operand of ?? or ||. This proposal intends the new expressions to be usable in any location where they can occur syntactically (and they can be enclosed in parentheses to become a <primaryExpression>, which means that they can occur basically anywhere).

This proposal may seem quite disruptive at the syntactic level, but an experimental change to Dart.g seems to support the assumption that we can simply do the following:

returnExpression // Updated, was `returnStatement`.
    :    RETURN expression?
    ;

breakExpression // Updated, was `breakStatement`.
    :    BREAK identifier?
    ;

continueExpression // Updated, was `continueStatement`.
    :    CONTINUE identifier?
    ;

rethrowExpression // Updated, was `rethrowStatement`.
    :    RETHROW
    ;

// Delete `returnStatement`, `breakStatement`, `continueStatement`, 
// `rethrowStatement` from `nonLabelledStatement`, they are now
// covered by `expressionStatement`.

throwExpression // Should be renamed, e.g., `abruptCompleteExpression`.
    :    THROW expression
    |    breakExpression
    |    continueExpression
    |    returnExpression
    |    rethrowExpression
    ;

@johnniwinther, @scheglov, @mkustermann, @sigmundch, how disruptive does this feature seem to be from your point of view, for the static analysis, code generation, or execution of programs?

My guess is that the static analysis can just give the new expressions the type Never, and almost everything done for throw expressions could then be reused with these new expressions.

But during code generation and execution there might be local state (say, a non-empty expression evaluation stack) that calls for further operations before jumping, and I have no idea how hard it would be to handle that, or how much of the existing functionality concerned with throw expressions could be reused with the new expressions.

@munificent, @jakemac53, @lhrn, @leafpetersen, @natebosch, @stereotype441, WDYT?

@eernstg eernstg added the feature Proposed language feature that solves one or more problems label Feb 7, 2022
@eernstg
Copy link
Member Author

eernstg commented Feb 7, 2022

Closing this issue: I discovered that #2025 already had very much the same proposal, so I just added a bit of analysis from this issue to #2025.

@eernstg eernstg closed this as completed Feb 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

1 participant