4 ms·
Why would the first example with the database be "shooting your own foot"? I'm not a Rust dev, but in other languages that code makes perfect sense to me.
by valenterry 5y ago
Why would the first example with the database be "shooting your own foot"? I'm not a Rust dev, but in other languages that code makes perfect sense to me.
- xondono 5y agoFor the same reason that keeping a shared excel file in a network disk is a bad idea. The closure can write to database, and after the call, there’s no way to know if it has already written, or even if it’s writing to it right now.
- valenterry 5y agoWell, without further ado that's true. But the callback could of course set a result type somewhere (so, behave similar to a future/promise) and then we could know if/when it is finished and if it was successfully, or if it's still running (or broke without an error). But that's not Rust specific, that's just plain language-independent logic no?
- xondono 5y ago> But the callback could of course set a result type somewhere [..] then we could know if/when it is finished That would be a Mutex<>, the author mentions it in the comments. This would solve the “writing at the same time issue”, but not the lifetimes, so you’d need another change. Instead of trying the mess of implementing special closures, you could just make your db static.
- uncomputation 5y agoWhat if you do: my_fn(|| { db.store(42); }); db.drop(); (Assuming you can just drop the database object, the semantics don’t really matter but the idea is the same.) The OP wants an easy way to do this but this is just not an easy thing to do. How can the closure guarantee that the database object will exist if my_fn decides to sleep for a couple seconds? Most languages do not have this problem because either: they use a garbage collector (Java and it’s cousins, Python, Go) or they are not safe (C, C++). Rust is in a particularly difficult (and ambitious and exciting!) intersection where this problem is tricky.
- valenterry 5y agoAh, I see. So if there was a way to mark the DB as "ephemeral" or so, then it would be fine, but since the compiler can't know if the reference isn't deleted/freed, it doesn't compile? If I got it right, then that makes total sense.
- kzrdude 5y agoRust has &mut references and & references. The `&mut Database` sort of implies that the Database handle doesn't do its own locking or other needed state tracking - it just relies on the exclusivity of `&mut` in Rust to be sure that nobody else is modifying the database handle at the same time. If the API used `&Database`, then it would have to be more flexible for simultaneous use of the handle. And then the closure would be (a bit) easier to call too, because it's not tracking that exclusive reference. If the API used a reference counted `Database` handle, then it would release even more restrictions of lifetime management, etc. You can implement all of these in Rust. In other languages, you usually end up with alternative two or three. If you try to simultaneously take alternative 1 and use it in a way that's not supported, that would be shooting yourself in the foot. Except Rust says compile error instead.