4 ms·
I don't understand the people who look at this and go "yep, we should have more of this language". It's complexity for its own sake.
by sk11001 2y ago
I don't understand the people who look at this and go "yep, we should have more of this language". It's complexity for its own sake.
- ryanjshaw 2y agoI'm really confused... Is all of this just the equivalent of `Enumerable.Empty<T>` or `yield return` in C#?
- sk11001 2y agoSo you do agree that other languages achieve the same thing with much less complexity?
- tcfhgj 2y agoNot exactly the same thing though
- MereInterest 2y agoNot quite, because the user of those would need to perform dynamic dispatch in order to iterate over the result. In the article, the returned iterator has a type that is known to the compiler, and so the caller’s code can be optimized much more effectively.
- Measter 2y agoI'll ignore the option of returning a Vec or Option, as the article already went over why these options were rejected, and concentrate on the later options. Firstly the `std::iter::empty()` attempt: The issue they had here came down to the signature of the function. What they wanted to do was return an `impl Iterator<Item=&N>`. This means that the function isn't naming the specific type it returns[1], only stating that it's an Iterator that gives some `&N`s. However, the return type of this function is still one, specific type. You cannot return two different types that are both iterators. That's why this one failed. Boxing: Instead, we can return a `Box<dyn Iterator<Item=&N>>`. This is roughly equivalent to a function in C# returning an `IEnumerabale<N>`, in that the actual type is hidden, and the work is done doing dynamic dispatch. This allows you to return different kinds of iterators, because the specific type is hidden away inside the Box. The downside here is that you're doing a heap allocation. OptionIterator: This one is actually basically just the first Option case from earlier but wrapped up in a nicer-to-use interface for the user because it implements Iterator in a way that transparently handles the Option. [1] Additionally, it's not even possible to name the type of the iterator here due to the filter closure being unnamable.
- Sharlin 2y agoNo, 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.
- bilkow 2y ago> It's complexity for its own sake. Hey, let's talk about the complexity here, I think there's reason for it! They wanted to use static dispatch so that the return type has more information on the logic being returned and is able to optimize better while also avoiding allocations at all. Reduced the original example (that doesn't compile) here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b86ca5ea3a01144058d21c655fe03edc https://play.rust-lang.org/?version=stable&mode=debug&editio... If you want to do what other languages do, you can just use dyn Trait (trait objects, dynamic dispatch) instead of impl Trait (concrete objects, static dispatch). It's less efficient and requires allocations, which is what other languages usually do, but all you have to do is wrap it in a Box. Example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=87d5e40205c95eeb1dfcbc7ad7671a41 https://play.rust-lang.org/?version=stable&mode=debug&editio... If you want to use static dispatch, then you have to look a bit more into it, there's a lot of discussion in the comments already but for this specific case Option's into_iter + flatten works fine, while Either is a more generic solution or you could even implement your own iterator for this use-case if you wanted to. I'd say the complexity here comes from the explicitness and being forced to make a choice: Don't care about performance? Ok, just wrap it in a Box and call it a day. Wants to take the most out of it? Then you'll have to look deeper into it.