Skip to content

Allow for and while loop to return value (without discussion of keyword names) #1767

Closed
@JelteF

Description

@JelteF

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:

  1. Use the same noloop block as is use in the other case. ("noloop")
  2. Use a second new block, from here on called nobreak. ("nobreak")
  3. 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:

  1. Make the nobreak block optional and "noloop" when it is not added. ("nobreak-noloop")
  2. 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:

  1. "nobreak-last-statement"
  2. "last-stament"
  3. "nobreak-noloop"
  4. "nobreak"
  5. "noloop"

Please comment if you have other ideas that could be used, or you have a different opinion en the proposed solutions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions