carbon-lang icon indicating copy to clipboard operation
carbon-lang copied to clipboard

Need an approach for `for (;;)` and `do`/`while`

Open jonmeow opened this issue 3 years ago • 14 comments

Noting two deliberate syntax gaps:

  • #340 omitted do/while.
  • #353 omitted for (;;).

There's been discussion on #syntax about how to address for (;;). I'm filing this issue to track that and do/while together because solutions may be asked to address both.

Also, due to a suggestion of focusing on other issues at the time being, we may deliberately not address these cases for a bit yet.

jonmeow avatar Apr 21 '21 21:04 jonmeow

I suggest we put both do {} while () and for (;;) (semisemi for) into Carbon.

Rationale: we need to be able to translate C++ code into Carbon code. Translating like syntax to like syntax will make this process less scary and easier to verify by hand.

We have a small budget of "novel" transformations, and I don't think we want to start spending it here where the incremental value to developers is small.

Carbon is built for evolution. One way we can evolve Carbon in the future is to invent the new, better, all-encompassing replacements for these control mechanisms and make them available as an automatic target for C++ and Carbon code alike.

And maybe 1% of very weird code stays back with for (;;) or do {} while () because translating it to anything else will require human-level understanding to untangle some gnarly control flow.

mmdriley avatar Apr 21 '21 22:04 mmdriley

Remember that #353 omitted the semisemi syntax altogether, not just the for (;;) special case. I think it would be somewhat weird if we added for (;;) but not other versions of semisemi for.

I also think we don't need it for now, since translating for (;;) to while (true) is straightforward and mechanical.

austern avatar Apr 21 '21 23:04 austern

Sorry, I was just using those as (unclear) shorthand. My suggestion is that Carbon provide semisemi for and a do/while loop.

mmdriley avatar Apr 21 '21 23:04 mmdriley

Yep, looks like I misread. Sorry for the confusion.

austern avatar Apr 21 '21 23:04 austern

To document some of the #syntax discussion:

  • Structured Programming with go to Statements by Knuth has been discussed.

  • I've suggested adding on loop to while and possible nothing else, as a minimal solution. For example:

    int i = 0;
    while (i < 42) {
      ...
    } on loop {
      ++i;
    }
    
  • Some kind of loop syntax per @chandlerc:

    loop var Int i = 0 while (i < 42) {
      ...
    }
    
    // Using things like Dahl's construct from Knuth's paper:
    loop var Int i = 0 {
      ...;
    } while (i < 42) {
      ...;
    }
    // Or:
    loop var Int i = 0 {
      ...;
    } while (i < 42)
    
    // Even for range based loops if we want:
    loop var Int i = 0 for (var T x in my_container) {
      ...;
    }
    
  • A lambda-based range per @zygoloid: for (int n : range(0, #0 < 10, #0++))

jonmeow avatar Apr 22 '21 01:04 jonmeow

To comment briefly on options:

The reason for not adding these (for (;;) and do/while) is they were non-critical (and as a reminder, I expect this bug to be low-priority). while was minimal functional control flow, and could replace both with extra effort. While adding them and evolving is an option, delaying their addition may help avoid anchoring bias; it's easier to add a new feature to fill an empty space than it is to remove a feature.

Also, a couple things to consider on range:

  • This is intended to be advantageous by addressing uses through a library feature instead of a language feature.
  • This may not offer a replacement for do/while.
  • In more complex uses of for (;;), range may turn out to be more verbose, which may be poorly received by developers.
  • If use-cases are trimmed down through other paths (such as range literals) then a slightly more verbose syntax that's provided through a library may be good for addressing remaining use-cases.

Overall, I think we can probably benefit from not making a decision for now, and simply keeping this issue in mind for a bit while we focus on other issues.

jonmeow avatar Apr 22 '21 01:04 jonmeow

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the inactive label. The long term label can also be added for issues which are expected to take time. This issue is labeled inactive because the last activity was over 90 days ago.

github-actions[bot] avatar Jul 28 '21 01:07 github-actions[bot]

It would be good if we have the following syntax like this:

for i =0 wr i < n stp 2 : Console.Print(i)

This would be better as modern languages don't have enclosing brackets. In the condition can be given after sql like where syntax. Also the statement after step (stp) would be like: stp 2 = ( I=i+2) stp -2 = ( I = I -2) stp 2 = ( I= I2) or if we want to use in normal mode we can use: for (i=0 wr i<n; I++) Console. Print(i)

Tomttth avatar Aug 15 '22 14:08 Tomttth

Consider how Python addresses this use-case:

for i in range(0, 10, 2):
    print(i)

Here, range is a function, not a fundamental language keyword like for or in. It returns an iterable object which for can use for values of i.

By moving functionality into libraries [instead of adding keywords], we're able to keep the language simple and make it easier to evolve in the long term. By reusing a singular for syntax, we're reducing how much developers need to learn about how for works, although somewhat by shifting that understanding to the functions used. I'd expect Carbon is heading in this direction for the particular use-case.

jonmeow avatar Aug 15 '22 15:08 jonmeow

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please comment or remove the inactive label. The long term label can also be added for issues which are expected to take time. This issue is labeled inactive because the last activity was over 90 days ago.

github-actions[bot] avatar Nov 14 '22 02:11 github-actions[bot]

Shuffling to a long-term tracking issue.

jonmeow avatar Nov 15 '22 00:11 jonmeow

Shuffling to a long-term tracking issue.

Just to give some context -- when discussing this, it didn't seem to actually have a question for the leads at this point. Mostly it is tracking a gap in the design that eventually we'll need to close (or decide not to close), but haven't yet. Until we have something concrete, not really an issue for the leads to answer.

chandlerc avatar Nov 15 '22 00:11 chandlerc

If you remember, in C++, for loops and while loops are almost equivalent, except in one case: when using continue I think it would be useful to have the ability to specify actions that happen after a continue statement, maybe something like this:

var i: u32 = 0
while (i < 10) {
    ...
    if (...) continue;
} then {
    i += 1;
}

Now this might be too simple an example, it might be solved with ranges (similar to python), but in many other instances this can be more useful (for example iterating over two iterables together).

And one more suggestion: Add the ability to label loops, this is useful when breaking or continuing in nested loops.

aviRon012 avatar Jan 31 '23 17:01 aviRon012

I also proposed a while/else construct in #471.

tkoeppe avatar Feb 02 '23 14:02 tkoeppe