Even a simple i=0, i=i+1 is "hiding" a lot in python then.
std::container<T> container;
for (std::container<T>::iterator i = container.begin(); i != container.end(); ++i) { ...}
auto iter = container.begin(); while (iter != container.end()) { ...; ++iter; }
for (auto const & t : container) { ... }It's not like 'for' is limited to counting in other languages. The grand-daddy in c does something until some condition is false, and that thing can equally be incrementing/decrementing a number or invoking some function. That's what a loop does in any case, it compiles down to a conditional jump (JNE/JE..)
Maybe his reason for astonishment is obscured by over-use of an LLM to 'enhance' the text.
Comparing to forEach in JS is incorrect because forEach is an method of Array.
You should compare it to `for...of` in JS. Both operate on iterators.
Article is missing an important distinction between iterators and other "array like" types (including strings):
Iterators don't have to stop, e.g., they can take from a generator that never ceases.
Both Python and JS are happy to loop forever if the iterator never stops.
C 'for' is a while loop. It's strictly syntactic sugar for an already existing feature. And it's really, really transparent. `for(A; B; C) { do_stuff(); }` isn't just a while loop, it's this while loop:
A;
while(B) {
do_stuff();
C;
}
Other languages have treated for as a separate concept from while. C isn't really informative in that case.
WhyNotHugo•1h ago
You can write the exact same loop with `let mut iter = v.iter(); while Some(x) = iter.next()`.
'for' loops in Rust are purely syntax sugar, and I somewhat wish they didn't exist. They provide you two ways of doing the same thing, but one of them hides the details from you. Having 'for' as a keyword is nice for folks coming from other languages, but then it hides the possibility of other interesting usages, like cloning an iterator inside a loop.
bigfishrunning•1h ago
rbanffy•28m ago
Martinussen•1h ago
tialaramex•58m ago
The value is in idiom, turning everything into loop expressions (The "while" keyword is also just sugar, Rust's only fundamental loop is named loop) makes it harder to discern what's actually going on.
If you want to clone the iterator in some cases rather than consuming it, that should look different so that reviewers will see what you're up to.
kevinmgranger•34m ago
It just so happens that for most collections, `IntoIter` is also defined for references to them, which typically gives you the same behavior that `.iter()` would give.
tialaramex•2m ago
https://doc.rust-lang.org/std/keyword.for.html explains how a loop is de-sugared
https://rust.godbolt.org/z/5jzhxYM51
... shows that today ranges like 0..5 aren't Copy even if that would be possible, which means if they're consumed they're gone, whereas an array of integers is Copy and so consuming it doesn't mean it's gone, you can just consume it again.
The desire is that Rust 2027 edition will change the nice syntax for ranges to produce new ranges like core::ranges::Range which are Copy if possible and only IntoIterator, the original ranges are never Copy but are Iterator, we now regret this choice.
saghm•22m ago