Quite honestly, looping with a counter is by far not the most common kind of loops you write in real code. It is the simplest kind of loop that they teach in clases

Looping with a counter might not be the most common kind of loop written, but indeed it is the simplest kind of loop that they teach in classes. "Make simple things simple" is a good principle that improves readability and teachability of the language. Also this proposal can be seen as a way to homogenize the loops, if something looks like a range, should be iterable as a range; right now C++11's range-for loop is used for many constructs that look and behave like ranges but leave aside the most simple of them: just iterate from number A to nomber B, in my opinión this is an oversight.

As a broad overview: simple loops should be simple, for fancy complicated custom iterations we have the traditional loops.

Are we really just worrying about saving a few keystrokes and typing slightly less?

Typing less is not a bad thing, the less visual noise the code has, the better for spotting typos/errors/bugs. That being said a non error-prone syntax is desirable, in my opinion the for (type variable = init : limit) is unbeatable and familiar thanks to C++11's range-for loop.

If you make the tuple solution more noisy, then you can have the precise control over types that you want:

for (auto [b,e,o] = tuple<T1,T2,T3>(...); ...)

This gets quite noisy, but it's still something that's possible today, and uses language features that are useful in more places than just for loops.

And the multiple-init 'for' loop quickly gets noisy too.

I really disliked the "use tuple" approach but I'm starting to like it tbh. Yet, it feels more familiar/natural to declare each variable in the traditional way, even if it gets noisy pretty fast.

@Filip
for ( N ) { … } // run N amount of times

Didn't think of that, looks good in my opinion.

Missatge de Jonathan Wakely <cxx@kayari.org> del dia dl., 10 de febr. 2025 a les 20:20:


On Mon, 10 Feb 2025, 17:15 Pau Miquel Montequi Hernandez, <pau.montequi@gmail.com> wrote:
Sorry for my misunderstanding Jonathan,

Indeed "I don't want to include a header" is not a justification, it is less nowadays if we just "import std;" as a whole.

Indeed. I didn't mention that because it's easy and glib to say "modules fixes that!" but in practice most people aren't able to rely on them yet.



My point is that something different can be achieved that is not possible with the tuple approach, like assigning an explicit type to each symbol, with auto […] = std::tuple(…) we are limited to use whatever type the compiler deduces which is not always the intention.

The explicitness of for (type_a a = …; type_b b = …; type_c c = …; condition, expression) provides in my opinion more control (I want exactly this type) and sense of intentionality (I wanted this to be like that), I cannot deny that it is not ideal to pollute the for with so much noise though, we can always move variables to the enclosing scope if we don't mind giving them a bigger-than-required scope and lifetime or use the tuple approach which is less noisy but more broad.

If you make the tuple solution more noisy, then you can have the precise control over types that you want:

for (auto [b,e,o] = tuple<T1,T2,T3>(...); ...)

This gets quite noisy, but it's still something that's possible today, and uses language features that are useful in more places than just for loops.

And the multiple-init 'for' loop quickly gets noisy too.




Missatge de Jonathan Wakely <cxx@kayari.org> del dia dl., 10 de febr. 2025 a les 17:46:


On Mon, 10 Feb 2025 at 16:03, Pau Miquel Montequi Hernandez <pau.montequi@gmail.com> wrote:
You're absolutely right! doing nothing is considerably easier than doing something :P

But afaik that's not the criteria to consider or reject proposals, maybe I'm wrong. Apart from the correct and true fact "If you include a header and write the loop 'like this' you can do the same" is there any other reason to end the discussion?

I didn't suggest the discussion should end. But I do think that avoiding the need to include a header is not a good justification for a language change.

Many C++ features exist precisely so that interesting and useful things can be done in libraries, instead of pushing more and more features into the core language.

A language feature to implicitly create a tuple-like type that can initialize a structured binding would allow you to write this without <tuple>:

  for (auto [b,e,o] = ?(in, in+size, out); ...)

but it would also be usable in other places, so would give more benefit than just alternative syntax for `for` loops.




--
Pablo Miguel Montequi Hernández.


--
Pablo Miguel Montequi Hernández.