8 ms·
How is Rust less complicated than C++? I don't use it, but from what I read it seems to be even more complicated, and getting even more so with the myriad of f
by mikevm 9y ago
How is Rust less complicated than C++? I don't use it, but from what I read it seems to be even more complicated, and getting even more so with the myriad of features they are adding each release.
- isido 9y agoA good, but difficult question - it's difficult to quantize complexity. Both languages have aim that their users can have much as much control as possible, even if it entails complexity in the language desing. Perhaps one answer could be, that much of Rust's complexity arises from the concepts of 'borrowing' and 'lifetimes' and how they are encoded in the language. In C++, complexity much of the complexity arises from the copy/reference semantics, and the possibility of overriding standard behaviour. You need to have wider context to understand local code. So you need to understand how the C++ works on quite a low level and you might need to know more specifics on your C++ codebase than might be the case in Rust.
- masklinn 9y ago> How is Rust less complicated than C++? In pretty much all senses of the word? > getting even more so with the myriad of features they are adding each release. It's far from adding a "myriad of features" with each release, and most of those it adds are library stuff, see for 1.23: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1230-2018-01-04 https://github.com/rust-lang/rust/blob/master/RELEASES.md#ve... And with respect to non-library features currently in-flight, by and large they are "playing catch-up" to C/C++ for compatibility or to fulfil use cases for which the language is not currently convenient or sufficient e.g. generics-over-values, const functions, allocators. Rust has an upfront feeling of complexity in lifetimes and the borrow checker, but here's the ugly truth: pointer lifetime issues don't exist any less in C++, the only difference is the compiler doesn't help you with them.
- jhasse 9y ago> pointer lifetime issues don't exist any less in C++, the only difference is the compiler doesn't help you with them. There's also the case though where the Rust compiler isn't helping you, but is just wrong. Must of them are going to be fixed by non-lexical lifetimes soon though.
- masklinn 9y ago> There's also the case though where the Rust compiler isn't helping you, but is just wrong. Bugs aside, compilers are not wrong, they may be too limited for what you're trying to do. Which is a different situation.
- jhasse 9y agoWell, most compiler bugs are cases where the compile "is wrong" and "being too limited for what I'm trying to do" also sounds like a bug. So this reads to me as "aside from when they are wrong, compilers are not wrong" ;)
- masklinn 9y ago> Well, most compiler bugs are cases where the compile "is wrong" Most compiler bugs are situations where the compiler allows stuff it should not or generates incorrect code. > "being too limited for what I'm trying to do" also sounds like a bug. So this reads to me as "aside from when they are wrong, compilers are not wrong" ;) Most every compiler is "too limited" to do some things, that is a big reason why dynamically typed languages are still a thing. For instance I can't tell Java to just take any object with an attribute "foo" despite it being the only thing I want to use (and I don't even care about its type) — bypassing the compiler via reflection aside. Do you think that's a bug in the compiler?
- jhasse 9y agoHm ... I wouldn say thats a limitation of the compiler but of the language itself (no ducktyping). Definitely not a bug though.
- loup-vaillant 9y agoBeing too limited for the intended purpose is still being wrong on some level. Not a bug, but still. Granted, sometimes you don't care: stuff like `true?1:"foo"` is of type int an has value 1, but the compiler will rejected because of a type mismatch in the conditional—but you don't care because the code smell is too big and obvious to ignore. Sometimes however you do care, if only a little: the value restriction in ML for instance prevent some function from being polymorphic because some side effect might break the type system. This forces you to eta-expand the function definition (no partial application, you need to write the arguments explicitly), which is a bit of a hassle in some cases.
- Santosh83 9y agoFor one thing, Rust has had the benefit of learning from the evolutionary lessons that languages like C++ went through. Another point is that really arcane stuff that's applicable only to very few legacy systems need not be supported, and aren't, while C and C++ don't have the luxury of dropping such support.
- lmm 9y agoIt seems to have many fewer language-level features. No lvalue/rvalue distinction, pointers are not elevated to a language-level feature (only references), only a very limited exception mechanism (panic) that doesn't try to generalize to support general validation (rather general validation is done with Result which is a plain old datatype written in the language, though admittedly it relies on a macro for use - more generally this approach is also used for things like I/O, a lot more is done with plain old library functions written in the language rather than added to the language standard), the macro mechanism is much less of a special case than the C++ preprocessor, no "const" and associated language-level complexity (e.g. "mutable"), smaller and more consistent syntax (no comma operator, no sequence point rules), more unifying things from the start (e.g. traits as values) rather than ad-hoc conversion rules in the language later on.
- masklinn 9y agoFWIW > Result which is a plain old datatype written in the language, though admittedly it relies on a macro for use It does not. It relies on a special construct (!) or macro (try!) for convenience, but these are not necessary (a popular alternative is to use the various HoFs instead) and desugar to pretty trivial (if possibly repetitive) code: macro_rules! try { ($expr:expr) => (match $expr { $crate::result::Result::Ok(val) => val, $crate::result::Result::Err(err) => { return $crate::result::Result::Err($crate::convert::From::from(err)) } }) }
- steveklabnik 9y ago(It's ? not !)
- masklinn 9y ago(You're right of course, not sure what I was thinking)
- lmm 9y agoI don't think Result would be seen as an acceptable replacement for exceptions without the macro/special construct. But I should've been clearer.
- edflsafoiewq 9y agoHere's one example: In C++, creating an instance of a class is fantastically complicated. The class must be initialized, and there is a zoo of different initialization forms: value, direct, aggregate, default, list, copy, etc. Which one foo {} invokes has been the subject of a spec bug. Some of these invoke a constructor, which is like a function, but isn't a function, multiplying the number of concepts involved further. Constructors suffer from bizarre syntactic limitations. They need a special syntax for handling exceptions. The form foo f(); famously declares a function instead of default initializing f. The [dcl.init] section of the spec is about 16 pages long and there are about another dozen about how constructors work in the special member functions section. In Rust, there is exactly one way to create an instance of a struct: you provide a value for each of its fields.
- pegasuscollins 9y ago> In Rust, there is exactly one way to create an instance of a struct: you provide a value for each of its fields. As a user of both rust and and C++, I certainly wouldn't consider the the lack of default constructors in rust to be a good thing. Especially for std types like Vec it is really annoying to have to initialize it explicitly. > The [dcl.init] section of the spec is about 16 pages long and there are about another dozen about how constructors work in the special member functions section. That is a bad argument if you're comparing to a language that doesnt have a spec. Maybe a complete, exhaustive rust spec would be much longer than the C++ standard?
- masklinn 9y ago> As a user of both rust and and C++, I certainly wouldn't consider the the lack of default constructors in rust to be a good thing. Especially for std types like Vec it is really annoying to have to initialize it explicitly. That is fair but orthogonal to the issue at hand, namely: > How is Rust less complicated than C++?
- pornel 9y agoRust mostly avoided accidental complexity. The complexity it has is mainly from tackling a complex problem of providing memory safety and preventing data races at compile time. In C++ a large chunk of complexity comes from legacy of being a C superset and having to preserve backwards compatibility with all of its old features and syntax quirks, and often surprising edge cases arising from interactions between different features.