3 ms·
> In the Rust snippet vector is moved into the loop, and thus freed. Do you see any code in the snippet that requires it to be? This could be a simple read-onl
by 59nadir 1y ago
> In the Rust snippet vector is moved into the loop, and thus freed.
Do you see any code in the snippet that requires it to be? This could be a simple read-only borrow because the actual logic of the program requires only that, and the value could live on happily after the loop. Literally nothing in this snippet requires anything else, you've just sort of assumed that the way Rust does it is the only thing that makes sense.
It's not about what Rust currently does, really, it's about what it ought to do.
- x-yl 1y agoAre you suggesting Rust should automatically insert the borrow annotation because it is able to see that a borrow is sufficient? That would be quite unintuitive and make it ambiguous whether a for loop is borrowing or consuming the iterator without reviewing the body. I'd strongly argue that it should unambiguously do either one or the other and not try and read the author's mind.
- 59nadir 1y agoYes, I'm suggesting it should do the right thing for the code the loop is actually trying to execute. I personally think this is exactly what Rust and its users have signed up for. I might be mistaken about that, but I think it's in line with the more general view that Rust is attempting to be as close as it can get to a language that reads like it has a garbage collector without having one.
- DougBTX 1y ago> the more general view that Rust is attempting to be as close as it can get to a language that reads like it has a garbage collector without having one. I've used Rust a fair amount, and I've never seen that expressed as a goal. A couple of general principles followed by Rust are to prefer explicit code over implicit conversions and to support local reasoning. Those are both present here: the borrow needs to be made explicitly, rather than implicitly based on code later on.
- Klonoar 1y agoThis is not at all what we signed up for. The explicit-ness is the point.
- ninkendo 1y agoIt’s important that a for loop takes ownership of the vec, because it’s the only way you can call things inside the loop body that require the element itself to be moved. If you don’t want the loop to take ownership of the vec, there’s literally a one character change: put a & before the thing you’re iterating (ie. for x in &y). That borrows the vec instead of moving it. You seem to want rust to decide for itself whether to borrow or own the contents, but that way lies madness… it will be really hard to reason about what more complicated code is doing, and changes would have very non-local effects on how the compiler decides to use your code. For me, move-semantics-by-default is the key idea that rust got right, and it’s a very simple concept. It’s not intuitive, but it’s the key idea behind all of rust’s benefits for memory management and preventing concurrency bugs. “Learn one simple but non-intuitive thing and you get these huge benefits” is a tradeoff I’m very much willing to make, personally.
- 59nadir 1y ago> You seem to want rust to decide for itself whether to borrow or own the contents, but that way lies madness… Most of what Rust does already feels like madness, like the concept of implicit moves, etc., but I understand your point. I don't think the reasoning really makes sense in terms of actual logic, but as I wrote in another comment: It's possible that I've misunderstood the sales pitch of Rust trying to be GC-less GCd language. > For me, move-semantics-by-default is the key idea that rust got right, and it’s a very simple concept. It’s not intuitive, but it’s the key idea behind all of rust’s benefits for memory management and preventing concurrency bugs. “Learn one simple but non-intuitive thing and you get these huge benefits” is a tradeoff I’m very much willing to make, personally. I can respect that and seen this way (where we accept that we're simply going to have unintuitive and incorrect rejections of programs) it does make a lot more sense.
- bombela 1y agoI find move by default refreshingly simple. I don't even understand what is so hard to understand about move. A move is a simple memcopy + the certainty that the source is unreachable. This is important if the memcopied object holds resources. Any new type is move only by default (no copy or clone). This is so that you can opt in willingly. Making a move type also copy is not an API/ABI breaking change compared to removing copy (or clone). And it's the same for clone not being the default. With clone you get to run custom code for cloning instead of a memcopy. Remind me again how move, copy and clone works in C++ /s
- SpaceNugget 1y agoThe code says to call into_iter and consume the iteratee, so rust does that. If you want a reference, use the &, just like in zig/c/c++/etc. You are saying an even more extreme version of "If there's a way what I wrote could possibly be interpreted that could compile, it should do that" ignoring the fact that there's almost assuredly _many_ ways that your code can be interpreted that could compile. Slowing down type resolution/compilation (by making every unannotated loop a generic T|&T) and adding more syntax (since rust would need new annotations to explicitly specify borrow/take in for loops), in order to save a single character that matches the behavior of most other related languages and is perfectly clearly explained by the compiler, is maybe a bad move. Considering compile time and complicated syntax are two of the biggest things people who actually write rust complain about.