3 ms·
> the use of "unsafe" features for the most basic tasks, such as implementing various collections. That's pretty much the _only_ place you need when using uns
by Manishearth 11y ago
> the use of "unsafe" features for the most basic tasks, such as implementing various collections.
That's pretty much the _only_ place you need when using unsafe, when implementing "basic collections". The point of Rust's unsafe is to be able to use it to design safe abstractions. This is not a con; this is the _point_ of unsafe.
(Also, one can argue that implementing a collection is not a basic task. It's taught very early on in courses as a way of teaching pointers, but collections aren't simple in general and especially when it comes to memory management. See also: http://cglab.ca/~abeinges/blah/too-many-lists/book/ http://cglab.ca/~abeinges/blah/too-many-lists/book/)
> it prevents concurrent modification, even when provably safe
Are you talking about non-lexical borrows here (that will be fixed soon), or about Rust's restrictions in threaded scenarios? You can alleviate some of the threaded restrictions via scoped threads. Most of the non-threaded ones can be fixed (without a performance penalty) using Cell (RefCell for non-Copy types, though there's a slight cost there).
I've been programming in Rust for a while now, and this doesn't turn out to be an issue in practice since the regular way of designing code avoids this pretty well. Programming in Rust as if it was C++ leads to these errors a lot more.
- tomp 11y ago> This is not a con; this is the _point_ of unsafe. It's not a con if you consider C; but it most definitely is a con for a language that advertises itself as having "guaranteed memory safety". > Are you talking about non-lexical borrows here (that will be fixed soon), or about Rust's restrictions in threaded scenarios? I'm talking about the fact that the programmer has to write the code/algorithms in such a way that Rust's very limited proof engine can handle them. This means using collections in a limited way - if the API doesn't support something, you can't do it (an example would be, splitting a vector and updating each element by a separate thread - IIRC that used to be a problem, maybe it has been fixed already?). This also means implementing concurrent algorithms using the (limited) API (Cells, Atomics, ...) - although that's probably the preferred way in C as well, I'm guessing even things like CAS can be abstracted away with zero cost while improving safety. I'm curious, though, how would I implement the following: I have multiple threads, and I only care about the last result (i.e. they can all write to the same memory location)? I agree, though, that this is rarely a problem in practice, which is why Rust is an amazing language. The criticism/controversy is mostly coming from outsiders and/or people like me who disapprove of false advertising in principle.
- Manishearth 11y ago> It's not a con if you consider C; but it most definitely is a con for a language that advertises itself as having "guaranteed memory safety". I explained in the other comment why this isn't really an issue. Note that most "basic datastructures" exist in the stdlib already, so you don't have to use unsafe code to do this in practice. 100% guaranteed memory safety by your definition is an unattainable goal. In safe rust code you do indeed have guaranteed memory safety, and you're able to extend this by writing unsafe rust code with which you supply your own guarantees of safety. Safe Rust and unsafe Rust are best viewed as separate languages with smooth FFI between them, see http://doc.rust-lang.org/stable/nomicon/meet-safe-and-unsafe.html http://doc.rust-lang.org/stable/nomicon/meet-safe-and-unsafe.... > splitting a vector and updating each element by a separate thread - IIRC that used to be a problem, maybe it has been fixed already? This is scoped threads and is possible. Crossbeam and scoped_threadpool both have solutions for this. > This also means implementing concurrent algorithms using the (limited) API That's what you should be doing for thread safety. Like you mentioned, that's what you do in C too. Rust does indeed have CAS atomics. > I have multiple threads, and I only care about the last result (i.e. they can all write to the same memory location) This sounds like a use case for monotonic (relaxed) atomic ordering? Not sure. Note that "the last result" itself doesn't mean anything, due to the way the cache works. There's no global clock (hooray for distributed systems!). The fact that Rust makes you think about this is a good thing. You can stick a Lamport clock in there, but that involves using more atomics and won't be as fast as relaxed ordering.
- steveklabnik 11y ago> an example would be This has not been a problem for quite a while. You call split_at_mut to get two &mut T's back, and then pass them to each thread.
- zerker2000 11y agoNon-atomic writes to a single memory location, from what may well be separate cores etc, happen essentially at random due to out-of-order execution. What are the downsides to using the value from the last thread ~spawned~, and calling it a day?