7 ms·
For those of us who are getting to the party 3 years late, thank you. Just my 2p for others learning: for me, Rc::RefCell was what I was missing, even after I
by mr_luc 10y ago
For those of us who are getting to the party 3 years late, thank you.
Just my 2p for others learning: for me, Rc::RefCell was what I was missing, even after I thought I was up to speed. I was fine using Channels for inter-thread communication and I never needed Arc, but use of Rc is common in the Rust ecosystem and a lot of my early fights with the borrow checker weren't fights I needed to have. In situations where it wasn't a trivial change, and I found myself banging my head against the wall, it was often because I was in a situation that called for a reference counted cell.
- cyphar 10y ago> Just my 2p for others learning: for me, Rc::RefCell was what I was missing, even after I thought I was up to speed. I started (and then stopped) learning Rust a few months ago (before their docs rewrite) and the borrow checker and concepts weren't explain in a way that I could understand. Programs wouldn't work at all, and when I read about Rc::RefCell I was scared because I wasn't sure how much garbage collection rust would do and whether or not it would actually be safe. So yeah. Rust definitely has problems for beginners.
- steveklabnik 10y agoTo be clear, Rust has no garbage collector, and unless you type "unsafe", it's safe. RefCell will panic when something goes wrong. I should take this opportunity to mention that the book has been stagnating because I (along with Carol Nichols || Goulding) have been re-writing it out of tree: https://doc.rust-lang.org/stable/book/ https://doc.rust-lang.org/stable/book/ The ownership/borrow checker stuff has been completely re-done. The existing book chapters explain it in the abstract; in the new book, we use String/&str as a motivating example, since that's an area that often trips up new Rust programmers.
- simcop2387 10y agoThat's great to hear. That's definitely an area that has made me slow down on learning Rust. Will definitely be checking out the new book once it's ready.
- wyldfire 10y ago> So yeah. Rust definitely has problems for beginners. IMO Rust has the challenges that are very similar to all other languages have. But if you are trying to make the leap from a GC'd language like Java or Python to Rust without ever having written C/C++, you should expect to have to learn not only new language concepts but new programming concepts.
- deleted 10y ago[deleted]
- cyphar 10y agoI'm a programmer that has been using C for at least 8 years, and I've been developing in Go for the past 4 (as well as a couple of years of Python here and there). The point is that I have experience in quite a few programming languages, and I am familiar with the programming concepts you're referring to. I do not agree that Rust's challenges are the same challenges with other programming languages. Because Rust will not let you even play with the langauge unless you understand how to write safe programs (which is a concept that is defined in Rust). So there's a whole bootstrapping problem of "how the hell do I play with this thing to understand it if I can't play with it until I understand it fully". C, C++, Python, Go -- none of them have this issue. They will let you write bad code and won't stop you from running it (which I admit is not a good thing, I'm just saying that Rust's strengths are not without their downfalls).
- mikekchar 10y agoI had a similar problem with the type system in Haskell. I'd look at Haskell code and it was obtuse to me. Even reading books, it was hard for me to understand some stuff until I started writing code... but writing code was difficult because I didn't understand it. For me the key was just doing toy problems over and over again. Without understanding the idioms, it's hard to dive in and write something real. I think Rust is approachable if you take it like that (or at least it was when I looked at it about 2 years ago).
- Manishearth 10y ago> I wasn't sure how much garbage collection rust would do Rust doesn't do magical garbage collection. Rc<T> does reference counting, which is a form of garbage collection, but you get to choose where it gets applied, so it's a linear cost with no magical GC pauses or whatever. Rc isn't unique to Rust, it exists in C++ too. RefCell makes mutation within an Rc safe. It panics if you misuse it. http://manishearth.github.io/blog/2015/05/27/wrapper-types-in-rust-choosing-your-guarantees/ http://manishearth.github.io/blog/2015/05/27/wrapper-types-i... has more on the Rc<RefCell<T>> pattern
- alblue 10y agoReference counting is not a form of garbage collection. Both reference counting and garbage collection are types of automatic memory management.
- Manishearth 10y agoThis discussion crops up each time reference counting is brought up. In academia reference counting generally falls under the umbrella of GC. In the industry "GC" usually means "tracing GC". The terminology is irrelevant to the point I'm making. I did make a distinction between RC and the "regular magical kind" of GC.
- alblue 10y agoGarbage collection requires a garbage collector, which reference counting doesn't have or need. This is true for both academia and industry.
- xorxornop 10y agoIt's still runtime memory management. That makes it garbage collection in my book. Sure it's not as involved as tracing, the prototypical form of GC, but it's still something that requires a runtime check each time that resource is used or a binding to it goes out of scope, similar to aspects in generational GC.
- isuraed 10y agoWhat kind of application s would Rust be an appropriate for? What languages is it largely meant to replace/improve on.
- biokoda 10y agoIt's meant as a c/c++ replacement.
- steveklabnik 10y agoRust is intended for applications where you need speed, concurrency, and safety/correctness. In some senses, "use Rust where you would use C or C++" makes sense, but we're also seeing a lot of usage from programmers who have rejected C or C++ for various reasons. One angle that we've been focusing a lot on lately is productivity. Think about some feature of Rust that provides safety, like out borrow checker, which ensures that pointers don't do bad things. One way to think about this is safety, but another way is productivity: if your application segfaults, you have to track down what actually caused it, and then what caused the cause: "oh this pointer was null because I did something incorrect in this other part of my code." While having the compiler do these checks can sometimes feel like a productivity _loss_ at the beginning, you do a lot less debugging later, so it's a productivity _gain_ overall. (Or at least, we feel that way.) Other features of Rust make it feel productive as well: a focus on iterators and composable iterator adapters is often more productive than manual for loops, Cargo and crates.io enable wide-spread code re-use[1], we've been working on good tooling for IDE integration for those that use IDEs, and "zero-cost abstractions" help you have nicer interfaces while not having to pay the cost for them. Like this: https://news.ycombinator.com/item?id=13117608 https://news.ycombinator.com/item?id=13117608 One interesting area where we've seen lots of production Rust usage is embedding Rust in other languages. Since Rust can expose functions that look like C to the outside world, you could write a Ruby, Python, Javascript, or whatever extension in Rust instead of C. And Rust's safety features are appealing here, since you may not be the kind of person who writes C all the time: that's why you write Ruby/etc in the first place. Soon, we expect to see more usage of Rust on the server: the "tokio" project is gearing up for an initial release, which provides a foundation for asynchronous IO. Even before tokio is released, people are playing with this: crates.io is Rust on the backend, and "npm recently began replacing C and rewriting performance-critical bottlenecks in our registry service architecture with Rust": https://medium.com/npm-inc/npm-weekly-73-no-love-for-http-urls-in-shrinkwrap-files-npm-%EF%B8%8Fs-rust-and-the-cli-asks-for-rfcs-8c082f558d52 https://medium.com/npm-inc/npm-weekly-73-no-love-for-http-ur... Basically, lots of places. We'll see how things go into the future! 1: Anecdote time: my favorite package is https://crates.io/crates/x86 https://crates.io/crates/x86, which provides low-level bindings to various x86 platform details. Writing an operating system? No need to define your own IDT entries, just grab the library and http://gz.github.io/rust-x86/x86/irq/struct.IdtEntry.html http://gz.github.io/rust-x86/x86/irq/struct.IdtEntry.html has you covered. Re-usable packages in operating systems is super cool. On a higher level, this kind of thing is enabling Firefox to re-use Servo components more easily; Firefox can just pull chunks of servo with (relative) ease.
- Manishearth 10y ago> Rc is common in the Rust ecosystem I'm really surprised you think that's the case. Most rust codebases I've worked with use Rc very sparingly, if at all. If a codebase does use Rc there's usually one central thing that is Rc'd, with everything else using regular memory management. I have noticed that beginners coming from GCd languages often tend to structure their code in such a way that paints them into a corner where they must use Rc. This might be what hit you. I'm not really sure how to teach idiomatic Rust though.
- echelon 10y ago> I'm not really sure how to teach idiomatic Rust though. Learners should read and write lots of Rust. That's a great way to learn what is idiomatic. There will be early missteps, but thankfully the language makes it more comfortable when you do things the right way.
- Manishearth 10y agoYeah, my advice in general is to pick a few rust codebases and start hacking on them. But I would love to figure out how to teach this in a way that doesn't involve random codebases. Some folks learn by doing (I do!), but others fare better with tutorials.
- mr_luc 10y ago> there's usually one central thing that is Rc'd, Right. In my case, I was using the nphysics library, which for unsurprising reasons uses Rc for entity handles. Similarly, in my app's code, I used nphysics' proximity and contact handlers to watch for events that indicated a change in status. Those handlers needed to initialize/set values in a HashMap accessible (and periodically cleared by) the main sim loop -- 'one central thing' that is Rc'd. It's not sprinkled everywhere in your codebase, and for obvious reasons most libraries don't need to use it. But in applications, a central loop + library-provided callbacks + some Rc'd state of doesn't seem too uncommon.
- amelius 10y agoReference counting can be a useful memory management technique. But reference counting may cause unpredictable pauses when large amounts of objects suddenly need to be freed (e.g. when dropping the last reference to a large array holding many references). At least a carefully written garbage collector can free objects incrementally, and concurrently. So memory management in Rust is certainly not a solved problem. EDIT: Removed mention of RefCell.
- Manishearth 10y agoIt's generally predictable pauses, fwiw. Well, a different kind of unpredictability from other GCs. And Rc is rare enough (IME) that this doesn't usually matter.
- steveklabnik 10y agoTo be clear, RefCell does not do reference counting, Rc does. RefCell does runtime borrow checking.
- kazagistar 10y agoI'm hoping for something like this a few years down the line: http://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/ http://manishearth.github.io/blog/2016/08/18/gc-support-in-r... Allowing Rust to generically adapt to an arbitrary Gc that it is nested inside of would be awesome.
- amelius 10y agoYes, that would be amazing.
- masklinn 10y ago> But reference counting may cause unpredictable pauses when large amounts of objects suddenly need to be freed (e.g. when dropping the last reference to a large array holding many references). Then again so does manual memory management if you're freeing a large object graph at once. > At least a carefully written garbage collector can free objects incrementally, and concurrently. You could get that with refcounting, stashing Rc0 objects in a list of items to free incrementally rather than freeing it all at once and synchronously.