4 ms·
I'm experienced in security and rust and I agree with mjg. I've probably written 100s of thousands of lines of Rust, and I've been in security for well over a d
by staticassertion 4y ago
I'm experienced in security and rust and I agree with mjg. I've probably written 100s of thousands of lines of Rust, and I've been in security for well over a decade.
None of what you said is even true, all of those patterns are trivial, except "back-references" which are very slightly non-trivial.
And none of it is relevant. We don't need another memory unsafe language. It's fine if it's a toy, but this obviously isn't. It causes real harm.
- verdagon 4y agoEverything I said is true. They all rely on having a mutable member reference to affect the outside world, which the borrow checker rejects. You can try to make it happen with a generic lifetime parameter for your structs, but you end up making invisible the thing you're pointing at, making it useless. One can use unsafe to have shared mutability, or sacrifice speed with Rc/RefCell (increments/decrements) or Cell (copying, especially bad when copying Vecs which causes heap allocations). Basic observers aren't possible. The closest thing we can get is some sort of modified observer-like substance that returns a command, which requires a lot of wiring and incidental complexity. [0] [1] Dependency injection (the pattern, not the framework) isn't viable for the same reasons as observers: you can't have a mutable reference field without causing a lot of headaches elsewhere. RAII isn't possible without sacrificing speed or safety. Most usages we see are backed by unsafe (FFI) or RefCell. We can't have multiple objects whose drop() affects the outside world, because we can't have multiple extant &mut references, and we can't just pass them in via parameters (because drop takes none). Back references aren't possible because of the circular problem (having a mutable reference to your owner means nobody else can read it). I'm not advocating for Hare, I'm just addressing the "I just don't see the excuse" remark, which can be ignorant of the costs of the borrow checker. The borrow checker is a great step forward, but not always a good tradeoff. An architect needs to be aware of these sacrifices before going all-in on a paradigm. [0] https://stackoverflow.com/questions/37572734/how-can-i-implement-the-observer-pattern-in-rust https://stackoverflow.com/questions/37572734/how-can-i-imple... [1] https://www.reddit.com/r/rust/comments/pwqju6/is_there_an_underlying_reason_that_idiomatic_rust/ https://www.reddit.com/r/rust/comments/pwqju6/is_there_an_un...
- staticassertion 4y agoRAII is built into Rust. DI is trivial and I use it all the time, idk what you're trying to say there. Graphs require Rc, backreferences are trivial with Rc::weak. idk what tot ell you
- Rusky 4y agoYou are fundamentally misunderstanding the relationship between Rust's unique and shared mutabilities and the usual mutability in, say, C. The Rust equivalent of C mutability is Cell. Conversely, the C equivalent of Rust's unique references is a `restrict` pointer. Cell is meant to be applied at the "leaves" of a type where individual assignments take place. When used this way, there is no additional copying relative to the straightforward C version. (Bringing up Vec and heap allocations here is also complete nonsense; Cell has nothing to do with Clone.) Once you wrap your head around that, all your shared mutability examples translate over to Rust trivially. All the "sacrifices" in speed you are imagining are relative to `restrict`/`&mut T`, not the usual baseline of a simple mutable object.