I believe that "i" is redundant as well, since most loops use "i" as the induction variable:

for (int = 0; 42) // Implicitly defines i as the induction variable.

Similarly, 0 is a common starting point, so it should be inferred:

for (int = ; 42) // Initializes i to zero

42 is the answer to Life, the Universe, and Everything, and most programmers are unable to think of another constant, so we could optimize for that as well:

for (int =; ) // Loop from 0 to 42

"int" is the traditional induction variable type, so no point in specifying it explicitly.

for (=;) // An integer loop from 0 to 42

The majority of loops are for loops (and while loops, and even non-looping statements, can be recoded as for loops), so

(=;)

Which could be compressed to a single character, U+1F92A "ZANY FACE":

🤪





On Mon, 2025-02-10 at 15:17 +0100, Pau Miquel Montequi Hernandez via Std-Proposals wrote:
Greetings,

I would like to discuss a revision of the for loop syntax, with the goal of evaluating possible improvements that could enhance its usability.

Common usage of for loops
The typical use case of a for loop is iterating over a collection of items when the number of iterations is known beforehand. More often than not, this means iterating one-by-one, yet the syntax requires explicitly specifying the increment operation:

for (int i = 0; i != 42; ++i) // Most of the time, ++i is the expected behavior


This raises the question: Can we simplify this pattern while keeping it expressive?

Proposal: defaulting increment and condition
One approach would be to default the increment operation to pre-increment and assume a typical end condition:

for (int i = 0; 42)  // Implicitly increments i and checks against 42


This unsettling syntax leads to another question: can we make it more intuitive?

Alternative syntax inspired by range-for loops
A syntax resembling C++11's range-for loop can be considered:

for (int i = 0 : 42)  // Iterates from 0 to 42
for (int id = get_first_id() : get_last_id())
for (auto i = v.rbegin() : v.rend())  // Reverse iteration


However, using colon (:) could be problematic since the C++11 range-for loop already follows a specific expansion involving std::begin()/std::end() and unary operator* which may lead to confusion.

Possible concerns and alternative syntax
The C++11 syntax assumes iterators and unary operator*, while this proposal does not. An alternative syntax can reduce ambiguity:
  • for (int i = 0 ... 42).
  • for (int i = 0 -> 42).
  • for (int i = 0 => 42).
  • for (int i = 0 <- 42).
  • for (int i = 0 <= 42).
Each has different implications, like <-/<= explicitly suggesting reverse iteration.

Also traditional for loops allow variables from the enclosing scope to be accessed on and after the loop, whereas range-based for loops do not, for consistency would the proposed new syntax force the same behaviour?

int x = 0;
for (x : 42) // Error?
    if (f(x))
        break;

return x; // Error?



Additional considerations
Some related improvements could be discussed in parallel:

Allowing a for loop to not require a named variable if it is not going to be used:
for (0 : tries) { if (try_to_connect()) return true; }


More flexible for loop initialization, allowing multiple init statements:
template <auto size>
void lcase(const char (&in)[size], char (&out)[size])
{
    for (auto b = in, e = in + size; auto o = out; b != e; ++b, ++o)
        *o = std::tolower(*b);
}


Feedback
I’d like to gather feedback on:
  • Is simplifying for loops for common use cases desirable?
  • Then, an alternative syntax is necessary or adapting C++11’s range-for loop could be a better approach?
  • If an alternative syntax is the best approach, will <-/<= and ->/=> provide a good way to express reverse iteration?
  • Will it be useful to extend range-for loop reach in order to allow the use of existing variables from the outer scope?
  • Any feedback about the additional considerations.

Looking forward to your thoughts.

--
Pablo Miguel Montequi Hernández.