5 ms·
Three different types of pointers? Perhaps that is going a bit far? > If you've a sharp eye, you're wondering what that "~" is that I snuck in on the type of t
by james4k 14y ago
Three different types of pointers? Perhaps that is going a bit far?
> If you've a sharp eye, you're wondering what that "~" is that I snuck in on the type of the closure for the child task. That's actually a pointer type, of which Rust has three (none of which can be null, by the way):
> ~T is a unique pointer to a T. It points to memory allocated in the send heap, which means data inside of unique pointers can be sent between tasks. You can copy unique pointers, but only by deeply copying (otherwise they wouldn't be unique!) (and by default, they are "non-implicitly-copyable", so the compiler will issue warnings if you copy them without writing the "copy" keyword).
> @T is a managed pointer to a T. Currently, these are reference-counted and cycle-collected (they may be full-on GCed in the future). Copying one increments the reference count, so multiple managed pointers can point to the same data. These are allocated on a per-task private heap, and cannot be sent between tasks.
> &T is a borrowed pointer to a T. It can point to the inside of arbitrary data structures - on the stack, inside ~ or @ pointers, etc. Rust has a static analysis, called the "borrow checker", that ensures that borrowed pointers must not outlive the scope of the pointed-to data (i.e., it is impossible for rust programs to have a use-after-free).
- kibwen 14y agoIt's not too daunting. `&` is your go-to pointer for most scenarios. `~` pointers are for anything you want to send to a different task. `@` pointers are for things you want to be garbage-collected.
- rohshall 14y agoFantastic summary of the pointers. It's less daunting now.
- scott_s 14y agoDo you have reasons why it's going too far, or is that just an emotional reaction? Consider that these pointer types map exactly to the pointer-type templates provide by C++11: unique_ptr, shared_ptr and weak_ptr: http://en.cppreference.com/w/cpp/memory http://en.cppreference.com/w/cpp/memory In the interest of starting discussion and not just stating facts, I will take the position that I think Rust's adoption of these concepts into the language is a Good Idea. Many pointer-based codes have these pointer types, but they are enforced through convention alone. C++11's templates are a step in the right direction, as they make explicit what convention assumes, but the compiler does not know about them. Yes, because they are template classes, there are certain things one can and cannot do with, say, a unique_ptr, but the compiler cannot do any analysis on the usage, because the concept has no representation in the language semantics. (Ben references a blog post by Niko Matsakis about some of the analysis Rust does: http://smallcultfollowing.com/babysteps/blog/2012/07/19/yet-another-tutorial-on-borrowed-pointers/ http://smallcultfollowing.com/babysteps/blog/2012/07/19/yet-...)
- _delirium 14y agoI agree they're good to put into the language semantics, but as a side point on C++11, couldn't the compiler actually assume a bunch of things about those templates, since their behavior is specified? GCC, at least, assumes many things about even C stdlib functions, because it "knows" what they do, so rather than treating them as just regular functions, it can make stronger assumptions about them when optimizing, and/or generate code to implement their functionality internally, rather than linking the library implementation.
- scott_s 14y agoYou can, but the difficulty, I think, is that this clean separation of pointer types exists along with naked pointers, including void*. That is, C++11 still carries the legacy of C's free-for-all, so the kinds of guarantees that one could get from a C++ compiler - even with baked in knowledge of unique_ptr, shared_ptr and weak_ptr - are going to be limited.
- cmccabe 14y agoA lot of the productivity gain in higher-level languages comes from not having to manage memory. Having three different incompatible, differently allocated pointer types to fool around with slows you down. The creators of Rust are hoping that the speedup from not having to do global garbage collection in most scenarios will balance out the loss of productivity. Personally, I'm skeptical. Azul showed us that pauseless GC was possible, even for Java. Android and .NET showed us that even without pauseless GC, the performance of GC'ed languages was adequate to build attractive user interfaecs. A lot of Rust's design choices mean that it's not really suitable as a web development or scripting language, and those two communities have shown themselves the most receptive to new languages. Mozilla has tried to rewrite their core product in a different language before. Look up "Javagator." It did not end well. But, who knows. Maybe this time really will be different.
- pcwalton 14y agoIt's not impossible to build attractive user interfaces with garbage collection, but it is significantly harder, both for users and developers of the system. Android system apps go to great effort to avoid using the GC during critical animations, while in iOS this is much easier. Implementing a good garbage collector is a lot of work, and it's very difficult to tune; even the JVM, which has had an enormous amount of man-hours put into it, struggles with GC pressure under some loads. Additionally, the applications we want Rust to be suitable for aren't competing with GC'd languages. They are competing against applications written in C++, with manual memory management and no automatic storage reclamation. They will be put head-to-head in benchmarks with them. We don't take performance regressions, and relying on global GC would be a significant risk. The Javagator is, in fact, an excellent example here! (As an aside, the pointer types are not all incompatible; all pointers can become &T, and the vast majority of functions take & pointers.)