3 ms·
No, it’s (slight) complexity for performance’s sake. Rust’s iterators are famous for how well they optimize, thanks to being generic, monomorphized, and thus in
by Sharlin 2y ago
No, it’s (slight) complexity for performance’s sake. Rust’s iterators are famous for how well they optimize, thanks to being generic, monomorphized, and thus inlinable and eligible to the full power of the optimizer.
If you want slow dynamic dispatch and extra heap allocs like in Java or C# or whatever, that option is available. But Rust would be laughed out of the systems programming table if its iterator abstraction were that inefficient.
In the future, please avoid resorting to strawman arguments stemming from ignorance.
- sk11001 2y agoLet me clarify that (1) I've written a decent amount of Rust before giving up on it (2) I'm not a systems programmer, all of the problems I work on can be solved with higher level garbage collected languages. The thing that I find baffling is when people start throwing Rust at problems that don't need it like backend services and APIs, CLI tooling, games. I'll take your word that the complexity is necessary in systems programming - the problem is that people are carrying that complexity everywhere else too, and it doesn't seem like a tradeoff that's worth it. Rust doesn't gradually expose you to concepts depending on your use case for the language, once something is needed for the lowest level use case, it becomes additional complexity which contaminates all other use cases.
- frou_dh 2y agoIf we judge by results and not some notion of appropriateness then in my experience a lot of the miscellaneous CLI software written in Rust is great and high-quality from a user perspective. So if their authors are indeed making things harder than they need to for themselves, then it must just show how capable they are that they're able to get great results anyway.
- biorach 2y ago> I'm not a systems programmer, all of the problems I work on can be solved with higher level garbage collected languages Great. Use those languages. Don't criticise rust for not being one of those languages > people are carrying that complexity everywhere else too, and it doesn't seem like a tradeoff that's worth it. Yes, there are people who have used Rust in places where a higher level language would be more appropriate. However rust has characteristics beyond raw performance that make it often a compelling choice in areas outside of systems programming. The complexity of the language brings benefits that may or may not suit a particular use case. Any criticism of necessity or otherwise of its complexity is just noise without talking about what you want to use it for.
- sk11001 2y ago> Great. Use those languages. I do. I'm not criticizing Rust, I'm failing to understand the people who choose to use it in places where it doesn't belong. Over time that's becoming an increasingly larger part of all the people who use it.
- steveklabnik 2y agoYour value judgments are not everyone else’s value judgements. That’s really all it comes down to. Just because you consider something inappropriate does not mean that that is a universal truth.
- sk11001 2y ago> Your value judgments are not everyone else’s value judgements. I opened with this, yes. I think people who use Rust for everyhing have poor taste.
- steveklabnik 2y agoIt sounds like you do understand, then.
- lowbloodsugar 2y agoI mean, sure, people do do that. But it seems like the use-case described here is one where the performance and robustness of Rust would be appropriate. And while I agree there are certainly people looking to push the boundaries, often too far, where Rust makes sense, the language and its ecosystem are also becoming more proficient.
- mustache_kimono 2y ago> Rust doesn't gradually expose you to concepts depending on your use case for the language, once something is needed for the lowest level use case, it becomes additional complexity which contaminates all other use cases. I guess, once you know it, the linked problem really doesn't seem that complex. Once you know it, you know the idiomatic solution will look like this commenter's: https://news.ycombinator.com/item?id=41472874 https://news.ycombinator.com/item?id=41472874 If it were any simpler to write, I'm not sure you'd have any confidence the code was doing what it should be doing/what you thought was on the label. But I also strongly disagree with the quoted notion. One would usually ease their way into returning iterators. Much more likely is one would do the simple thing and allocate an empty Vec for awhile, or an Option<Vec<T>>, like the author even tried first, and then decide you want to be fast or, more likely, ask whether this is what was holding you back, and try to decide how to do that. > It's complexity for its own sake. I do agree that Rust can be complex, but this is not complex. This is just the Rust way. Right now, complex Rust, to me, is refactoring the code of others. The code of others has a certain weight/concreteness in Rust that sometimes makes it hard to mold into something else. Rust makes small refactorings a breeze. It makes some large refactorings feel almost impossible.
- inferiorhuman 2y agoVec::new doesn't allocate anything, so by extension an empty vec won't allocate anything. Option<Vec> doesn't really save (or cost) you anything here either.
- neonsunset 2y agoTo be fair, the way IEnumerable<T> works is more of a historical fact. The underlying type systems allows you to implement the same monomorphized iterators like in Rust, which some third-party libraries do. The main limitations are at the language level - the lack of associated types and high order functions being opaque means that for nested iterators you may end up writing unwieldy generic signature by hand, and instead of lambda - manually writing a value-delegate-like struct. In a brighter tomorrow, it will be a matter of the language doing so on your behalf, but in either case there is nothing preventing another guest language or even C# itself in the future having identical iterator abstraction implementation to Rust within the existing type system (unlikely to happen in C# as-is because it would be a huge breaking change, the compiler is getting better at inlining and devirtualization so in the simpler cases it may become not needed).
- petertodd 2y agoTo be clear, in this case if you don't want to think about it, and just want to use dynamic dispatch, you absolutely can! Just return a boxed iterator for the normal case, and a boxed empty iterator for the special case. Rust's dynamic dispatch will basically mean they're both the `Box<impl Iterator<Item=T>>` type, which is actually implemented with an allocation and vtable. Everything will work fine. You can optimize it later if it actually matters. I've done this type of thing plenty of times when working on non-critical code where I just wanted to get something to quickly work without thinking about it too hard.
- dundarious 2y ago> Rust’s iterators are famous for how well they optimize Perhaps famous for how well they optimize away the extrinsic overhead of the iterator concept. Not really famous for how well they optimize compared to just writing the loop and iterate code naively with indices or what have you. And the latter makes it far easier to adapt to use SIMD, sentinel values, etc. Please avoid implying that Rust has the objectively best tradeoffs for all situations. (See how annoying it is to be on the receiving end of condescension?)
- inferiorhuman 2y agoNot really famous for how well they optimize compared to just writing the loop and iterate code naively with indices or what have you. Sure they are. The loop will have to bounds check at each iteration, the iterator won't necessarily have to. Collect may save on the number of allocations, etc, etc.
- dundarious 2y agoNeither of those are intrinsic issues.
- inferiorhuman 2y agoSo?
- dundarious 2y agoSo why compare it against an artificially hobbled alternative and say "that's the awesome power of Rust!" when it does a bit better. Compare it against an alternative that is not hobbled with extrinsic issues.