Description
Introduction
I noticed #961 didn't seem to go anywhere because of the discussion about the name of the new block. That's why I just started working on an RFC with the new block name that IMHO seemed to have the least issues, namely the !break
one. However, I found out a lot of behavioural details where not actually decided on or discussed.
What this discussion is about (spoiler: not names of keywords)
This is why I want to start a new thread to discuss these details and not the names of keywords. The names used in this issue are not meant as final keywords for an RFC. They are simply meant to allow a discussion without confusion. After the issues here are settled, the names for the keywords can be discussed again in #961 or in a new issue.
Problems
The new proposal would allow for
and while
to return a value with the break
statement, just like proposed for loop
in #1624. We need extra behaviour because for
and while
can exit without a break. However, this can happen in two different ways. Either the loop body is never executed (for
with an empty iterator or while
with a false condition at the start). Or the body is executed at least once, reaches the end of the loop body or a continue
statement and then the loop stops (e.g. because it's out of elements or the condition has become false).
Solutions
For the case where the body is never executed another block is required that can return a value, this block is from here on called noloop
. For the cases where the loop would be executed I see three main solutions. These are below with short names that are used in the rest of this issue between brackets:
- Use the same
noloop
block as is use in the other case. ("noloop") - Use a second new block, from here on called
nobreak
. ("nobreak") - Use the value from the last statement that is executed, which can be
continue
. ("last-statement")
Then there are also two combinations possible of the options option above:
- Make the
nobreak
block optional and "noloop" when it is not added. ("nobreak-noloop") - Make the
nobreak
block optional and "last-statement" when it is not added. ("nobreak-last-statement")
My opinion on these solutions
The "noloop" option seems like the worst choice, as it does not allow to differentiate between the two different cases. The "nobreak" option seems better in this regard as it allows to have different behaviour for both cases, but is more verbose in cases where the behaviour should be the same. The "nobreak-noloop" solution allows to have different behaviour for both cases, but is concise when this is not needed.
The "last-stament" option has a big usability advantage over the previous ones, because it allows returning of a value used in the last iteration. However, this comes with the disadvantage that when this is not needed all possible endpoints need to return the same value, i.e. the end of the loop and all continue
statements. With the "nobreak-last-statement" solution you can work around this disadvantage by using the nobreak
block.
This reasoning is why I think the solutions can be ordered from most desirable to least in the following order:
- "nobreak-last-statement"
- "last-stament"
- "nobreak-noloop"
- "nobreak"
- "noloop"
Please comment if you have other ideas that could be used, or you have a different opinion en the proposed solutions.