[QUESTION] cpp2 for loops
dutkalex opened this issue · comments
Hi! My question is rather simple, but I could not find the answer in the documentation nor in other issues. What is the cpp2 equivalent for:
for ( int i = a; i < b; ++i ){
// loop body
}
All the examples in the documentation seem to be range-based for loops, and the closest I could find (which is obviously not the right answer) is:
for std::views::iota{ a, b } do ( i ){
// loop body
}
Thanks for the amazing work!
Best regards,
Alex
That's a good question I should cover somewhere. Here's the quick answer:
auto cpp1() {
// Prints: 0123456789
for ( int i = 0; i < 10; ++i ){
std::cout << i;
}
std::cout << "\n";
}
main: () = {
cpp2();
// Prints: 0123456789
(copy i := 0) while i < 10 next i++ {
std::cout << i;
}
std::cout << "\n";
// Same, just my personal whitespace style
(copy i := 0)
while i < 10
next i++ {
std::cout << i;
}
std::cout << "\n";
}
Line by line (and why I like being able to write the parts on individual lines):
(copy i := 0)
: Any statement can have statement-local parameters, so this is just declaringi
as anint
that's local to the loop. Parameters by default areconst
(and for not-cheap-to-copy types bind to the original value), so because I want to modify it I usecopy
to explicitly declare this is my own mutable scratch variable. (I find that statement-local parameters initially take getting used to the first couple of times, then are easy to remember and use because they work with any statement including blocks.)while i < 10
: The termination condition.next i++
: The end-of-loop-iteration statement. Note++
is always postfix in Cpp2.
I should add an example to the docs... I'll keep this open until I do that. Thanks!
Now added here: https://hsutter.github.io/cppfront/cpp2/functions/#for-while-do-loops
Thanks!
@hsutter You closed this thread but it turns out that your answer left me with more questions! 😅
- I understand that one of the goals of cpp2 is simplification of the language through generalization and an overall reduction of the number of concepts. But in this case, having to revert to a
while
loop is a net loss in expressivity of the language. I we were to follow this principle dogmatically, allfor
loops would have to be eliminated because every for loop is just a special case of the more general and powerfulwhile
loop concept. However, thewhile
loop is much-more error-prone, and I am sure you will agree that we don't want this kind of concept count reduction because havingfor
loops in our toolbox enables us to better express our intent as programmers. For scientific computing purposes (I take this example because this is where I come from as a C++ programmer), not being able to express in a simple way index-based iteration patterns would be a deal-breaker. However, I do not advocate for the error-prone C-syntax either, but IMO having a concise syntax such asfor idx_range(a,b) do (i){ ... }
available is important to make cpp2 code safer. What do you think of it? - I understand how the
for
loop syntax is built asfor <range> do <lambda_expr>
, which is actually very familiar to me as a HPC fellow, because we are used to writing thinks likehpc_framework::parallel_for( exec_policy, range, [&]( int idx ){ ... } );
in cpp1 syntax. However, the absence of the prefix:
from the cpp2 lambda syntax in the cpp2for
loop syntax, combined with the fact that the cpp2for
loop syntax does not read left to right is a sign that this generalization is not very natural. I would also add on a personal note that I really don't like thedo
token, because it does not convey much meaning as a keyword, and is confusing because it connotes ado
...while
loop. IMHO it is like having athen
keyword after anif
statement: it makes the syntax more verbose and does not provide any additional meaning. On top of that, having ado
token justifies diverging the syntax from theif
andwhile
syntax which both require the body to be enclosed by curly braces. I would argue that having a coherent syntax among these 3 control flow structures should be a higher-priority goal than seeking unification with the function syntax. With this in mind, my question is therefore: why not opt for a more intuitive syntax for the cpp2for
loop? For example, Python'sfor i in range(N)
is very natural and reads like english (they did a really great job on this one IMHO), and something like<optional label :> for <optional in(default), out, inout or move> <elm> : <range> { /* body with mandatory {} */ }
would be simpler, more familiar, easier to read and more coherent with the rest of the cpp2 syntax? What do you think of it?
Anyway, thanks for the quick answer and the amazing work overall
Best regards,
Alex
Moving this to discussions (see #1073), as it seems more appropriate