|
Rust released the alpha version of 1.0 recently, meaning there's finally a (mostly) stable standard library and feature set, so I figured it's about time we had a thread about it. What is Rust? Rust is a statically typed, compiled, systems programming language with a significant amount of safety built into the compiler. The goal of Rust is to be used in situations similar to where you would use C or C++, but provide features in the language to keep you safe from the hard parts of systems programming like leaking memory, race conditions, dangling pointers, and other. Rust has a heavy emphasis on zero cost abstractions in the language to provide all that safety. The compiler enforces these safety guarantees so that you can be reasonably sure that if your code compiles, then your code is correct and safe. Since this safety is enforced at compile time your program can run just as fast as the C or C++ program, hence the zero (runtime) cost abstractions. While Rust is a systems language and stays mostly true to the C abstract machine model, it also has a lot of influence from functional languages. Here is an example of some idiomatic Rust to some all even numbers from 1 to 1000: Rust code:
What makes Rust so safe? The most defining feature in Rust is its ownership model. In Rust, each resource (stack memory, heap memory, file handle, struct, etc.) can only have one owner and this ownership is enforced by the compiler. A resource is automatically freed anytime its owner goes out of scope. The ownership model enforces that only one thing can make changes to a resource at any given time. If you require multiple objects to have ownership of a single resource, that can be introduced as necessary with per variable reference counting. An owner of a resource can control the resource's deallocation, lend the resource out to borrowers, or move the ownership to a new owner. When lending a resource out (also known as borrowing), a resource can be borrowed immutably by any number of borrowers or borrowed mutably by one borrower. If a resource is borrowed immutably, no modifications can be made to that resource (by the borrowers or the owner). If a resource is borrowed mutably, only the borrower may modify the resource. All of this comes together to enforce memory safety without additional runtime baggage. This does, however, have compile time baggage and significant learning curve baggage as you struggle to satisfy the borrow checker. Rust has runtime bounds-checking of Vector and array access, so no more straying off into random memory. Rust strongly discourages unmanaged pointers by requiring the unsafe{} keyword around all usages. Safe code in Rust by default has no null values. Nullability can be added back in if required with the Option type that is so commonly used in functional languages: Rust code:
Rust code:
Because you're a bored and interested nerd like me. Because you've had your fair share of memory leaks and segfaults using unsafe languages. Because people on Hacker News keep talking about it and you want to offer your lovely opinion to the lovely discussion. Where can I learn more about Rust? Official Website: http://www.rust-lang.org/ Official Guidebook: http://doc.rust-lang.org/1.0.0-alpha/book/ Language Reference: http://doc.rust-lang.org/1.0.0-alpha/reference.html Rust By Example: http://rustbyexample.com/
|
# ? Jan 15, 2015 04:52 |
|
|
# ? May 6, 2024 01:49 |
|
Oh gently caress me I'm bad at making threads. poo poo post ahoy.
|
# ? Jan 15, 2015 04:56 |
|
I believe you'll find the superior title is "I left my compiler in the rain and got Rust". E: But seriously, I've played with it and it's great once you get used to the memory semantics. The community is also surprisingly nice and helpful. I'm not sure how widespread adoption will be, but I hope it becomes a big language. It also isn't afraid to crib all the best features from other languages. Haskell-like type systems, Go's channels, and so on. Linear Zoetrope fucked around with this message at 08:13 on Jan 15, 2015 |
# ? Jan 15, 2015 08:00 |
|
Jsor posted:It also isn't afraid to crib all the best features from other languages. Haskell-like type systems, Go's channels, and so on. Isn't this (in a bad way) what made C++ go wrong?
|
# ? Jan 16, 2015 18:05 |
|
I don't think the new features of C++ are hampering it as much as the legacy cruft that is continuing to be supported along with it.
|
# ? Jan 16, 2015 19:51 |
|
More specifically that the features added to C++ are (have to be) done in a way that's backwards compatible to not only it's own ~30 year history, but also a 40 year old predecessor language. Needless to say, the syntax of the new features is terrible.
|
# ? Jan 16, 2015 21:30 |
|
I toyed with Rust when it was 0.6~ and I am looking forward to trying it again. Is there a recommended autocompletion tool?
|
# ? Jan 19, 2015 11:59 |
|
Shinku ABOOKEN posted:I toyed with Rust when it was 0.6~ and I am looking forward to trying it again. If you use vim or emacs, there's racer.
|
# ? Jan 19, 2015 12:26 |
|
I've been waiting for a thread on Rust to pop up, as I'm far to lazy to have made my own. I've got a couple of fun little projects going in Rust, the largest of which is slowly shaping into something of a game (that only consists of a terrible animation system/scene manager/ai with behavior trees as of yet). Super thrilled that it's finally hit its big 1.0 (alpha)! Though most of the standard library is marked as unstable and likes to stare threateningly at my codebase with maniacal intent to break any and all of my builds at a moments notice. Certainly liking the language so far, as someone who primarily codes in C and Lua for fun, C# professionally, and tends to avoid C++ like the plague. All of the big Rust irc chatrooms on irc.mozilla.org are all super active as well, with people that love to chip in and help with things. So I'd highly recommend parking yourself in one or more if you want to seriously delve into Rust.
|
# ? Jan 24, 2015 23:26 |
So I'll ask this thread's first stupid question. How does ownership work with arrays, vectors, etc? If I add a Foo to an array or vector, does that array gain ownership over the Foo? Hopefully it's clear what I'm asking here, if not I can try to whip up some code to clarify.
|
|
# ? Jan 29, 2015 07:44 |
|
VikingofRock posted:So I'll ask this thread's first stupid question. How does ownership work with arrays, vectors, etc? If I add a Foo to an array or vector, does that array gain ownership over the Foo? Hopefully it's clear what I'm asking here, if not I can try to whip up some code to clarify. Looks like it moves unless you implement copy: http://is.gd/VR7qVk E: Note that it's considered borrowed if you box it too. Linear Zoetrope fucked around with this message at 08:57 on Jan 29, 2015 |
# ? Jan 29, 2015 08:52 |
Jsor posted:Looks like it moves unless you implement copy: http://is.gd/VR7qVk Thanks, that makes sense. Now that I think about it I think that has to be the case--otherwise stuff like this wouldn't work: code:
|
|
# ? Jan 29, 2015 09:13 |
|
Me too. I spent forever yesterday struggling with cryptic lifetime errors until I learned that new methods should return by value and not by pointer. It seems to be a Rust pattern to allow the code requesting the object to dictate its mutability/reference status.
|
# ? Jan 29, 2015 09:18 |
|
Once you get over the initial hurdle of everything bitching at you about lifetimes and learning the ~Rustic~ approach to things, like always returning just a plain bit of value and letting the caller decide if they want to box it (unique pointer to heap allocated memory), stick it on the stack, atomic reference count it, etc, things really start to click and you can appreciate the beauty of what they're trying to do with the language. Then you get to things like structures holding references to data or non object-like trait objects, and get to start the whole process over again while idly scratching at your head. The documentation is already loads better, and I'm fully anticipating a much wider array of user friendly tutorials, examples, and eventual books to start pouring out as more and more of the rust standard library gets that wonderful Stable stamp of feature lockin. Of course they just completely broke most libraries by renaming the core io module to old_io in anticipation of redoing the whole drat thing, so we still have awhile to go yet before we get our true 1.0 release.
|
# ? Jan 29, 2015 23:06 |
space kobold posted:Once you get over the initial hurdle of everything bitching at you about lifetimes and learning the ~Rustic~ approach to things, like always returning just a plain bit of value and letting the caller decide if they want to box it (unique pointer to heap allocated memory), stick it on the stack, atomic reference count it, etc, things really start to click and you can appreciate the beauty of what they're trying to do with the language. Is there a guide somewhere to doing things the ~Rustic~ way? I've made my way through the Guide and Rust By Example but I haven't really absorbed stuff like what kind of value to return.
|
|
# ? Jan 30, 2015 20:28 |
|
space kobold posted:Once you get over the initial hurdle of everything bitching at you about lifetimes and learning the ~Rustic~ approach to things, like always returning just a plain bit of value and letting the caller decide if they want to box it (unique pointer to heap allocated memory), stick it on the stack, atomic reference count it, etc, things really start to click and you can appreciate the beauty of what they're trying to do with the language. I have to admit, the thing that confused me about it was largely that once things are immutable they can't really become mutable, and I'm not really clear why it suddenly works when you wrap it in a new function. I have an example to explain my confusion: http://is.gd/l5A2hj I can do code:
code:
However, this gives a compiler error: code:
Linear Zoetrope fucked around with this message at 20:42 on Jan 30, 2015 |
# ? Jan 30, 2015 20:38 |
|
Dang, Rust looks way nicer than I remember it looking butBognar posted:When lending a resource out (also known as borrowing) People around here* like to misuse the word 'borrow' in normal speech like 'hey, borrow me that' and it's nails-on-the-chalkboard inside my head in the same way 'I downloaded that to you' is and that reminded me of that misuse for some reason. *E: meaning the place where I live, not SA Munkeymon fucked around with this message at 23:40 on Jan 30, 2015 |
# ? Jan 30, 2015 20:59 |
|
Thanks whoever fixed the thread tag
|
# ? Jan 30, 2015 21:20 |
|
Munkeymon posted:Dang, Rust looks way nicer than I remember it looking but From what I've seen, the compiler uses "borrow" properly. All the errors say things like "x has been borrowed by" or "but x was borrowed <here>".
|
# ? Jan 30, 2015 22:31 |
|
When Rust was first getting attention I remember a lot of discussion about it having built in support for concurrency like the Go language. Recently when I hear about the language everyone talks only about the memory safety aspect of the language. Does Rust still have built in support for concurrency, or am I not remembering things correctly?
|
# ? Jan 31, 2015 02:33 |
|
PlesantDilemma posted:When Rust was first getting attention I remember a lot of discussion about it having built in support for concurrency like the Go language. Recently when I hear about the language everyone talks only about the memory safety aspect of the language. Does Rust still have built in support for concurrency, or am I not remembering things correctly? They dropped that cooperative green threads system so that it's only merely a library, instead of being something inseparable from the language (or more substantially, inseparable from the rest of the standard library). There's still aspects of the language that pay homage to concurrency, though, like how you can only have one mutable borrow at a time (if I'm not mistaken). sarehu fucked around with this message at 02:36 on Jan 31, 2015 |
# ? Jan 31, 2015 02:34 |
|
sarehu posted:There's still aspects of the language that pay homage to concurrency, though, like how you can only have one mutable borrow at a time (if I'm not mistaken). This isn't really an homage to concurrency, it's required to safely implement things like a growable vector. If you could mutably borrow a Vec twice (or take out a mutable borrow while also borrowing it immutably), you could end up with a pointer to memory no longer owned by the Vec (like in the classic C++ case of appending to a std::vector while iterating over it). The language does still have some built-in nods to concurrency with things like the Send and Sync traits, which respectively mark types as being safe to send from one thread to another and mark types which can safely be aliased immutably from multiple threads.
|
# ? Jan 31, 2015 04:39 |
|
Oh. For some reason I was only thinking mutable borrows on multiple threads would be a bad idea because I did not consider how coarse-grained borrowing would affect other things. If only they had typestate so that you could express borrowing more precisely...
|
# ? Feb 2, 2015 19:04 |
|
Here's a neat little project where they've built a Minecraft world renderer in Rust: https://github.com/PistonDevelopers/hematite
|
# ? Feb 11, 2015 23:20 |
|
I'm currently working on building an Entity Component System for a (potential) game I'm making. Only just started a few days ago, but it's slowly shaping up. Current usage looks like: Rust code:
edit: link removed, no longer valid. space kobold fucked around with this message at 20:43 on Mar 9, 2015 |
# ? Feb 14, 2015 23:54 |
|
I tried to make an ECS too. How did you make the list of components? I couldn't figure out how to make a separate list for each component generically.
|
# ? Feb 15, 2015 00:10 |
|
I made a huge macro that builds a static list of components, using some unsafe blocks to manipulate the signature for each components array of data. Bit hacky, but it seems to work. The list is constructed like so: code:
space kobold fucked around with this message at 20:43 on Mar 9, 2015 |
# ? Feb 15, 2015 00:15 |
|
Yeah, a macro was my intuition, but I haven't ventured into macro land yet. Looking at yours will probably be educational.
|
# ? Feb 15, 2015 00:20 |
|
blog.rust-lang.org posted:Rust 1.0: status report and final timeline http://blog.rust-lang.org/2015/02/13/Final-1.0-timeline.html We've got a release date folks!
|
# ? Feb 15, 2015 17:09 |
|
Y'know, I think the worst thing about Rust is when the borrow checker can't prove something obviously safe is safe. If you have a function like fn get_something(&mut self) -> &mut MyType, and you match on self in the function, you absolutely cannot use any `ref`s on a pattern where you want to return self or Rust will refuse to acknowledge the borrow ends when the match is evaluated and the function returns.
|
# ? Feb 27, 2015 09:07 |
|
Jsor posted:Y'know, I think the worst thing about Rust is when the borrow checker can't prove something obviously safe is safe. If you have a function like fn get_something(&mut self) -> &mut MyType, and you match on self in the function, you absolutely cannot use any `ref`s on a pattern where you want to return self or Rust will refuse to acknowledge the borrow ends when the match is evaluated and the function returns. I don't think I understand your description of this particular problematic case, but in general yeah -- it can be very annoying when a borrow is held for much longer than it needs to, and you have to resort to scope convolution to satisfy the borrow checker. pcwalton had that huge patch to add "SEME regions" to later support non-lexical borrow scopes but it never landed, and I doubt anything like that will land before 1.0 :-\ Deus Rex fucked around with this message at 19:36 on Feb 27, 2015 |
# ? Feb 27, 2015 19:33 |
|
Here's an example of what I'm talking about. Basically pattern matching on mutable things can be bad: http://is.gd/l61Zav code:
|
# ? Feb 27, 2015 22:44 |
|
Looking at some linked list code, such as http://doc.rust-lang.org/0.12.0/src...t.rs.html#37-41 or some other linked list I saw, I notice that they wrap the unsafe pointers in a Rawlink<T> type. What is the purpose of doing this? Right now I assume it's so they only have to say "unsafe" in one place, or some bogus pretense at safety by making the value accessible only via an Option type as if null pointer dereferences were the danger and not use-after-free. Am I wrong?
|
# ? Mar 4, 2015 16:04 |
|
So the beta is out. I've been keeping my eye on Rust for a while and downloaded it. It seems pretty cool so far!
|
# ? Apr 14, 2015 12:33 |
|
The best part about it is that everything in it is more or less feature locked and fairly stable, so every single library in existence isn't going to break every other week so long as they're building against the beta.
|
# ? Apr 14, 2015 19:57 |
|
space kobold posted:The best part about it is that everything in it is more or less feature locked and fairly stable, so every single library in existence isn't going to break every other week so long as they're building against the beta. I did run into a bunch of feature gates I had to switch back to nightly for, though. Some of the stuff in collections is really, really useful. I can live without box syntax, but the collections feature has some really good stuff in it. What's the general stance on using generic parameterization purely for static side effects? That is, parameterizing a function with type T to alter its behavior. I had several algorithms (specifically, a multi-armed bandit solver) and I decided to make a function like: code:
Linear Zoetrope fucked around with this message at 07:55 on May 5, 2015 |
# ? May 5, 2015 00:00 |
|
A reason to do that is to avoid making virtual function calls. If the behavior of the solver was not entirely defined by the type, you could pass in the solver as a function parameter of type T (or reference to T or something) and still get that advantage. Reasons not to do that: compile time, executable size, performance costs of code bloat. Edit: If virtual function call performance is not a concern, I'd go with the version that uses virtual function calls. Either way, at the call site you're going to be parameterizing the behavior of the function, either as a template parameter or a runtime parameter. It is perfectly reasonable for a thing parameterizing the behavior of a function to be an "object". sarehu fucked around with this message at 02:00 on May 5, 2015 |
# ? May 5, 2015 01:56 |
|
I've got one dependency that only compiles on the 1.1 nightly, and another dependency that only compiles on the 1.0 beta. Welp. So much for my earlier prediction of things being much more stable and uniform as we approach that big 1.0 release.
|
# ? May 7, 2015 20:50 |
|
space kobold posted:I've got one dependency that only compiles on the 1.1 nightly, and another dependency that only compiles on the 1.0 beta. Welp. Obvious solution is to compile half your program as a cli executable and call it from the other half
|
# ? May 7, 2015 22:12 |
|
|
# ? May 6, 2024 01:49 |
|
space kobold posted:I've got one dependency that only compiles on the 1.1 nightly, and another dependency that only compiles on the 1.0 beta. Welp. Guhh? What's the one that compiles on the beta but not the 1.1 nightly? That sounds like a regression that should be reported...
|
# ? May 8, 2015 07:18 |