3 ms·
Since C++ ranges kinda look like Rust iterators, but I believe Rust doesn't have this problem, can somebody explain why? What's the difference? Or maybe it also
by panstromek 2y ago
Since C++ ranges kinda look like Rust iterators, but I believe Rust doesn't have this problem, can somebody explain why? What's the difference? Or maybe it also has that problem?
- tialaramex 2y agoI expect (but I'm not sure) it's because Rust iterators are a deliberately thinner, less powerful idea. Suppose I give you a Rust iterator A and a C++ range B. You can ask A for the next() item and get back an Option<Item>, this literally iterates as an inherent part of getting your answer, there's no current() or previous() and there's no separate finished() if you ran out of items you got None instead of Some(item). A can be asked for a hint about how much is left, but it's allowed to say it has no useful idea: between zero and more than you can count, inclusive. B is expected to provide a richer, albeit unsafe, API. I believe somehow this means it's only reasonable for B to cache answers, as it can be asked to give the same answer again and it'd be inefficient to re-calculate it, whereas there is no way to ask A to repeat an answer so it makes no sense for it to cache (obviously there are special purpose Rust iterators which can have any feature, but the Iterator trait itself doesn't need to cache).
- panstromek 2y agohm, so I tried this on the playground and it seems like Rust iterators also scale super-linearly in debug mode (which is expected, because every adaptor creates a new local that contains the previous one plus something extra), but this seems to go away in release mode (as everything is inlined). Is the problem in C++ something different?
- jcelerier 2y agoit's exactly the same behaviour in C++. but people are used to this behaviour in Rust while in C++ they're used to writing traditional for-loops which do not have such an overhead at -O0 over -O3
- pornel 2y agoRust's iterators are single-use streams of items, and nothing more. A Rust iterator can be fully implemented by a closure that either returns the next element or signals it's done. This minimalist interface composes well, especially that it always uses single ownership, so there's always only one copy of the state accessed only from one place. They can't describe collections. They don't remember their beginning. They don't need to know their end until they reach it. They can't be sorted. They don't need to support splitting or iterating in reverse.