3 ms·
Rust has built-in semantic support for iterators; the compiler knows about the Iterator and IntoIterator traits and has specific syntax (the for expression, als
by solar-ice 4y ago
Rust has built-in semantic support for iterators; the compiler knows about the Iterator and IntoIterator traits and has specific syntax (the for expression, also known as the "iterator loop expression") to use them. In fact there is no direct semantic support for the type of loop you are talking about.
- throwaway17_17 4y agoRust does have a for in construct that is implemented in terms of iterators. However, Rust certainly has a while loop also defined as a part of the language. The docs.rust-Lang also defines a loop construct that is only exited with a break statement. So there is clearly semantic support for a looping construct that just loops over code and can contain an incrementing index variable. I would have to check the intermediate language, but I assume the for in construct is implemented, at the semantic level as an iterator object inside a while or basic loop construct. Edit — I just checked and docs.rust-langexplicitly states that the for in construct is ‘syntactic sugar’ for the common case of looping over a container that implements the iterator trait.
- solar-ice 4y agoA while loop is not semantic support for incrementing a number on each loop. It is semantic support for checking a condition on each loop. You can increment a number yourself, but at that point you're doing something where there is significantly better language support for just using iterators. You may as well claim Rust has semantic support for, idk, bubblesort, because you can write bubblesort with it.
- throwaway17_17 4y agoAs I said in my edit, the Rust docs explicitly call out the for..in construct as syntactic sugar over a loop which contains an iterator in the body, i.e. 'or-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common practice within Rust, which is to loop over anything that implements IntoIterator until the iterator returned by .into_iter() returns None (or the loop body uses break).' [1] In fact that same page gives the expanded code on it. It directly expands to code using the iterator's .next() method on each go through the loop. So, I think since the difference between the iterator semantics, as defined and describe by the Rust documentation, and using an index variable and incrementing that variable on each loop are not different enough for your exaggerated claim regarding 'semantic support'. But, I'm not trying to convince you to not use iterators or that iterators are not useful in some projects. I don't particularly care what other developers decide are the correct standards for their projects. My initial comment for this sub-thread was just trying to point out that I tend to view a language's semantics at the base level, where iterators are programmer implemented features defined for specific types, and that there is a definite difference between using iterators and using a loop with an index variable for container access. I don't think I was wrong to make that observation, and the Rust docs seem to support that difference. That's all I was getting at. [1] - https://doc.rust-lang.org/std/keyword.for.html https://doc.rust-lang.org/std/keyword.for.html
- solar-ice 4y agoUsing the iterator's .next() method in a loop - or the built-in expression for doing so - avoids maintaining an integer counter and indexing. It is simply not semantically the same thing, and you cannot approximate what iterators get you with your counting loop in safe Rust code. The difference in semantics is why one enables you to avoid overflow checks and the other does not, given the semantics of Rust which don't allow skipping those overflow checks in safe code. At a "base level", every language is exactly equivalent - they are all approximations of a turing machine - so I really don't get that argument unless you are trying to argue that every language is really just C in disguise.
- sophacles 4y agoSure it there is: for i in 1..n { some_mut_arr[i] = T::default(); } // OR mut i = 0; while i < n { do_something(some_arr[i]); i += 1; }
- solar-ice 4y ago1..n is an iterator. The while loop is torturing the poor language - it is using the wrong tools to achieve a goal that is much better achieved using the things it does have direct semantic support for.
- sophacles 4y agoI see what you mean by "semantic support" now. Fair enough that 1..n is an iterator, however it's not an iterator over the array we're manipulating. As for the while loop "torturing the poor language" - that's you injecting some preference. It's perfectly valid rust, and there's plenty of situations that look close to what I wrote (albeit my example was distilling down those cases to the core) and which aren't easily achievable without contortion to get everything into an iterator. Don't get me wrong - I really like iterators. Sometimes though, iterators add obfuscation, particularly after the 5th or 6th chained iterator method.
- tialaramex 4y agoRust only really has one loop, it's named loop and it's an infinite loop (you break to leave it). So just as Rust's "for" is syntactic sugar, so is "while", it will de-sugar into loop with an exit condition break at the start, since that's how while works in Rust. But this sort of illustrates how limited your model is, you're assuming the way loops worked in some language you've more experience with, probably C, is just "how loops work" but it's a weird feature of one language invented decades before the present, but decades after the fundamentals. It's like fixating on how the brakes worked on the 1971 Ford Cortina. That's not "how car brakes work" it's just how the brakes worked on that particular model of car, a brand new BMW i4 and a Model T are both equally reasonable examples of "how car brakes work".