7 ms·
When people say "Rust is just as complex as C++," I think value categories are a great example of why it's actually simpler, even if it also seems complex. C++
by steveklabnik 1y ago
When people say "Rust is just as complex as C++," I think value categories are a great example of why it's actually simpler, even if it also seems complex. C++ has three primary categories: prvalue, xvalue, and lvalue. There's also glvalue and rvalue. Rust has two: a place (which is a glvalue) and a value (which is a prvalue).
C++ needs those extra categories, they exist for good reasons. But it is more complex.
- Sharlin 1y agoTo be fair, though, Rust really needs something morally like prvalues, to solve the heap initialization problem aka `Box::new([42; 10_000_000])`
- steveklabnik 1y agoYes, it is possible that Rust will add more complexity here specifically, but also just in general. Just how it goes :)
- okanat 1y agoI am not so sure. A purely type-system-based API (in place initialization + MaybeUninit ?) or a new "static" Vec type can already solve most of the problems with Box::new([val; N]).
- steveklabnik 1y agoRight, that's why I think it's possible, but not for sure. There are other ways than new value categories to solve these problems.
- tialaramex 1y agoI think what you'd most likely do here is something like: const HUGE: usize = 10_000_000; let mut values = Box::<[i32]>::new_uninit_slice(HUGE); for k in 0..HUGE { values[k].write(42); } let values = values.assume_init(); Edited to fix early enter oops, typo in loop length that'd be caught if I'd tried this.
- phire 1y agoOnly problem with that approach is that assume_init() is unsafe (because it depends on you getting the initialisation loop correct), and many people are (correctly) hesitant to use unsafe. IMO, it would be really nice if the naive syntax was guaranteed to work, rather than requiring programmers to remember a new workaround syntax (new_uninit_slice() was only stabilised a year ago). This edge case is a little annoying because the naive approach will usually work for a release build, but then fail when you with back to a debug build.
- tialaramex 1y agoYes, sorry, too late to edit now but it should use an unsafe block for the assume and provide the safety rationale explaining why we're sure this is correct. I am sympathetic to desire to make it "just work" in proportion to how much I actually see this in the wild. Large heap allocations, initialized in place in a single sweeping action. It does happen, but I don't reach for it often. Often people say "Oh, well I will finish initializing it later but..." and now we're definitely talking about MaybeUninit 'cos if you've only half finished the Goose, that's not a Goose yet, that's a MaybeUninit<Goose> and it's crucial that we remember this or we're writing nonsense and may blow our feet off with a seemingly harmless mistake elsewhere.
- csmantle 1y agoThis will soon gets cumbersome if we're trying to construct some large struct literals (rather than arrays) directly on heap. Rust should be able to elide the unnecessary stack allocation here.
- koito17 1y agoAdditionally, the "r" and "l" may lead one to incorrectly guess that rvalues and lvalues are related to their position in an expression. But alas, they aren't; there are lvalues that cannot appear in the left-hand side of an expression.
- mzajc 1y agoAre you referring to consts? Besides those, I can't really think of a counterexample.
- tonyarkles 1y agohttps://en.cppreference.com/w/cpp/language/value_category.html https://en.cppreference.com/w/cpp/language/value_category.ht... There’s some weird examples here involving functions, function pointers, template parameters, and a few other things.
- nutjob2 1y ago> cannot appear in the left-hand side of an expression Do you mean assignment?
- rich_sasha 1y agoI'd say the complexities of Rust just lie elsewhere. Building a linked list is trivial in C++ (well, third time round, after two segfaults), whereas in Rust it requires a degree in borrow checker ology. But yes, I used C++ extensively about 20 years ago and no longer understand any new developments in this language.
- ithkuil 1y agoWriting linked lists in rust is super easy (just use box, rc etc). Writingefficient linked lists in rust OTOH requires more advanced concepts. But that's because the language gives you more guarantees about safety than C++. That safety is not only important for the implementation of your code but also for the memory safety of your code when combined with other code that calls your code
- malkia 1y agoSo it's easy, but complicates matter later.
- ithkuil 1y agoyep, as it should, since memory safety with explicit memory management is complicated. If you use a language that allows you to do it in a non-complicated way it's just shifting the complication somewhere else, and if you're not aware of that you will likely have an unsafe program that will contain memory safety bugs (which often become security issues)
- steveklabnik 1y agoYou can write it in Rust with unsafe the same way you would in C++, so it's at least equivalent.