3 ms·
> * Partial borrow. > The status of this is unclear. It does work in many cases. It's complicated. I would push back a little on the "no good reason" though, bu
by giovannibajo1 8y ago
> * Partial borrow.
> The status of this is unclear. It does work in many cases. It's complicated. I would push back a little on the "no good reason" though, but this is gonna be long so I'll leave it at that.
Not all partial borrows are safe, but a lot of them are. Most programmers know how to write safe code coming from different languages without borrow checker; they do put bugs sometimes -- that's true -- but most of the times the code I write is safe. It's just that there's no way to tell Rust that it is, and the workaround has a global impact on the code being affected (it forces to split structures, which greatly increases the cognitive load in reading and writing the code).
> * Rc/RefCell/Box
> Yes, this is painful, but that's because shared ownership is painful.
But the point is that I do NOT want shared ownership. What I want is to have a single owner of a long-living object, and several long-living references to it in other objects. When I say "long-living", I mean that the liveness of those objects is not visible through the call stack, so I can't use borrowing references. The only way to model this today is with shared ownership, which implies more than I would be willing to imply.
The same problem is apparent when trying to implement the callback pattern (which I forgot to list in my OP). Callbacks are basically impossible to do in Rust, and I found out I must have used callbacks everywhere in my last many years of programming in different languages, because I feel helpless in Rust when structuring code without being able to register and use callbacks.
> This is perceived as a good thing; if you code changes later to use threads, you're not hosed.
This does not sound very Rustecean :) If Rust is not opinionated and gives me full power with zero cost overhead, why does it force me to pay for thread-safeness (overhead) so that I can use threads later (opinion)?
Notice also that code which is not thread-safe doesn't prevent me from using parallelism. It just prevents me from moving objects across threads. But I can surely leverage the power of multi-core with threads, as long as the thread-unsafe objects are created and used within a single thread. So I'm not sure why I should make them thread-safe... just because I want to use them in a non-const global.
> If you want something that's not for multi-threading, then don't use something that can be used with multiple threading! TLS is probably what you actually wanted here.
What I want is actually much simpler: let me initial globals with runtime code that the compiler schedules for me to run before main. C++ does that very well; Go does that optimally. Either approach is good enough.
PS: TLS is potentially overhead again: indirect reference on non-PIE binaries.
> Rust is pickier about numbers than many langauges; 1u32 + 1u8 doesn't compile either.
I love that "1u32 + 1u8" doesn't compile, I hate integer promotion. What I'm saying is that "1u32 + {integer}" compiles, while "Wrapping<u32> + {integer}" doesn't. I think it's been a bad tradeoff to force people to use generics for wrapping integers when generics are still not good enough to implement a type which behaves like a native integer on common operations like "+ {integer}" or "as <type>".
- steveklabnik 8y ago> But the point is that I do NOT want shared ownership. Yeah, to me it sounds like you exactly want shared ownership. What you're describing is what shared ownership is. > Callbacks are basically impossible to do in Rust, I wouldn't go that far; yes, sometimes you need to do that dance for them, but not super often. It feels like maybe we've had wildly divergent experiences here :) > why does it force me to pay for thread-safeness (overhead) so that I can use threads later (opinion)? Because you're using a feature that can be accessed through multiple threads, even if you're not doing it now. If you use the version that can't, then Rust doesn't force you into it. > let me initial globals with runtime code This, in many cases, will be solved with `const fn`. But that runs at compile time, not before main. Life-before main has a ton of issues and is a huge pain.