8 ms·
Why Rust's ownership/borrowing is hard
- viperscape 11y agoTry a temporary variable for state, then use the consume in a scoped let block.
- dikaiosune 11y agoThere were also some interesting comments yesterday when this was posted to the Rust subreddit: https://www.reddit.com/r/rust/comments/45gcmh/why_rusts_ownershipborrowing_is_hard/ https://www.reddit.com/r/rust/comments/45gcmh/why_rusts_owne...
- gulpahum 11y agoThere was one good point, which was also my conclusion: "Given all that, I wonder if it makes sense to prefer plain old functions most of the time. Is that right, or am I overlooking something?" The response was yes. Avoid impl methods which take a mutable self.
- steveklabnik 11y agoI wouldn't characterize it this way. There was a whole thread on just this question: https://www.reddit.com/r/rust/comments/45j6ua/why_dont_we_prefer_plain_functions_over_impl/ https://www.reddit.com/r/rust/comments/45j6ua/why_dont_we_pr...
- cm3 11y agoWhy is move the default? In many code bases the number of immutable references outweighs that of pointers.
- dikaiosune 11y agoFor me at least, it's nice to have a language feature which tells me "BTW, the borrow checker is about to start caring about how long this memory is around." As opposed to the opposite, which is that everything you ever do will trigger the lifetime checks for passing arguments, and you would have to explicitly tell it to go away and that you want ownership to move. Edit: I'm referring to the `&` operator which creates a reference/pointer to the memory it precedes.
- cm3 11y agoYou mean it's forcing you realize this and restructure your code to free resources early like an eager collector?
- dikaiosune 11y agoThat's one pleasant effect (although a bit orthogonal to what I was referring to), because my default behavior in Rust is to pass ownership which results in that memory being dropped as soon as it's no longer needed. I guess what I'm referring to is that I think reasoning about the borrow checker is easier when references are opt-in instead of being the default. That behavior is re-enforced by the fact that the language's default is ownership. So I only end up needing to think hard about the lifetime of a variable when I've decided to (or been explicitly forced to) use references. I think it's a good way to reduce the cognitive burden of an already unfamiliar mechanism. EDIT: This also gets at one of my favorite parts of Rust: so many choices have been made in designing the language and standard library that make it so easy to do things "the right way" (either through those things being the default, or making it hard to do stupid things, etc.).
- steveklabnik 11y agoThat way the syntax is the same everywhere. Reference by default would look different, and then you'd need a sigil for move, etc. pcwalton said that back in the 0.1 days this was actually implemented, and it was very confusing.
- cm3 11y agoI remember it but the language changed so often that I didn't recall this right away. At least it's tried and scrapped and not based on some opinion.
- cm3 11y agoI mean, like in Haskell the hard earned wisdom is that laziness should probably have been opt-in like OCaml making you write the rec keyword for recursive functions. I hope that one day we will get TCO in Rust as it's natural to implement many things recursively.
- riffraff 11y ago> in Haskell the hard earned wisdom is that laziness should probably have been opt-in like OCaml is it? I am no haskeller, but I think I have seen some presentations or read papers in which lazyness by default was mentioned as something that haskell got right. Do you have some links to read up on what you say?
- jonreem 11y agoIn early rust, you actually did need to explicitly write `move` to move a value. However, this was extremely annoying as you move values a lot so moving was changed to be the default, which is far more tolerable. EDIT: There still is a `move` keyword, but it is used to indicate that closures should take ownership of their environment vs. just borrow values from it, not to move individual values.
- deleted 11y ago[deleted]
- jorgecurio 11y agoShould I learn Rust in 2016? What are you guys building with it and why Rust in particular?
- ajdlinux 11y agoYes. I'm still just learning it myself - I've got to say it's a really nice break from writing C (which is most of my day job). Having a proper type system is really nice, and having type inference makes me feel like I'm coding in a dynamic language even though I'm not. I'm currently building a CI tool (which will hopefully be open sourced once I get approval from our legal department) with a colleague of mine who mostly chose to use Rust because he needed an excuse to learn it...
- dikaiosune 11y agoI've found it very fruitful. I had previously spent a couple of months hacking away at a project in C++ which needed lots of fine-grained parallelism and custom data structures (metagenomics analysis tool). When we decided to shift our approach and that we wouldn't be saving any code, I started out trying Rust and fell in love. Many of the issues I faced in trying to quickly put together an application in C++ were just non-issues as a result of Rust's type system.
- pjmlp 11y agoOne of our customers is using C# for sequencing and it is quite fast for his datasets. Of course, using Rust is even cooler.
- dikaiosune 11y agoYes it is :). Also, I've had mixed results with managed languages and loading 1.5 TB text indices into RAM (not even to say anything about how much of NCBI's nt database will fit into 1.5TB when using different runtimes), so using manual memory management seems like the smart move here. Also, C++ had many libraries we could lean on for manipulating very large genomics datasets, and Rust is starting to grow a little ecosystem as well. I'm not familiar with a comparable availability of open source tools in C#, although I don't have any experience in it so maybe that lack of exposure isn't reflective of the state of things.
- jerf 11y ago"Rust's ownership/borrowing system is hard because it creates a whole new class of side effects." I'd submit it doesn't create them... it reveals them. They've always been there. Almost every other language fails to shine the light on them, but that doesn't mean they aren't there. All GC'ed languages still have issues of ownership, especially if threaded, and all non-GC'ed languages have all the issues Rust has... it's just that the language doesn't help you.
- pron 11y ago> I'd submit it doesn't create them... it reveals them. They've always been there. Hopefully, but not necessarily. Any (decidable) type system rejects well-typed programs (i.e., it "uncovers" problems that are not actually there), and the borrow checker is no exception. You will write some correct Rust programs that the borrow-checker just can't verify. This means that you will need to explain yourself in more detail (through more work) to the type checker, even though there was no mistake in your program. I think this is a good thing (depending on your requirements), but it isn't free.
- Animats 11y agoExactly. C programming has three big questions: "How big is it", "who releases it", and "who locks it". The language gives little help with any of those issues. C++ tries to address all three, but the mechanisms were all painfully retrofitted using templates and they leak. In the example in the article, "is_origin(point)", the code for which is not shown, is clearly bogus. A function that's just a predicate should not consume its input. It should use read-only access by reference. One big advantage of Rust is that, because the ownership checking is safe, you don't have to make copies of things just to simplify memory allocation control. In some C++ GUI libraries, strings are copied again and again to prevent memory allocation errors. Rust should be more efficient. It's going to be interesting to see if Servo puts a dent in browser memory consumption. It's insane that browsers now can need more than 1GB of RAM. There have to be multiple copies of the same data.
- pcwalton 11y ago> It's going to be interesting to see if Servo puts a dent in browser memory consumption. It's insane that browsers now can need more than 1GB of RAM. There have to be multiple copies of the same data. Most of a browser's memory consumption usually consists of JS and DOM objects. In effect, the pages you're visiting are actually doing the bulk of the allocations, not your browser.
- jupp0r 11y agoComing from a mainly C++ background, I find that the Rust language makes best practices in languages with manual memory management (and to some degree also in garbage collected environments) explicit. This is a great property of the language and it definitely changed the my C++ programming. You can see it as automatization of the more boring aspects of code reviews.
- Manishearth 11y agoI am from a more mixed background, but I have had my fair share of C++ before I learned Rust. Now when I code C++ my Rust knowledge is a double edged sword. On one hand, I have a much better idea on how to manage my data in C++. I had this discipline before learning Rust, but I didn't have explicit rules to it; it was just a ... nebulous bunch of idea about how data works. Now it's explicit. On the other hand, I am absolutely terrified when writing C++ code (something I would do with ease in the past). Well, not exactly, but it's hard to accept somewhat-unsafe code (which is probably safe at a macro level -- i.e. safe when looked at in the context of its use) and while I can see that something is safe, I can also see how it could become unsafe. And I fret about it. Rust trains you to fret about it (more than you would in C++, that is), and simultaneously Rust handles it for you so you don't have to fret about it :) C++ doesn't handle it, but you still fret about it sicne Rust taught you to. I guess it's a "Living is easy with eyes closed" thing :P
- imtringued 11y ago>Nothing in the experience of most programmers would prepare them to point suddenly stopping working after being passed to is_origin()! I'm not even a Rust programmer and only read three paragraphs about the borrow checker and I instantly saw that point is moved.