3 ms·
The feels are not very accurate. Rust adopted C++-like syntax to look less weird to C++ programmers, but semantically it is quite a different language. It's mor
by pornel 3y ago
The feels are not very accurate. Rust adopted C++-like syntax to look less weird to C++ programmers, but semantically it is quite a different language. It's more like a low-level Ocaml than C++.
Notably:
• Rust doesn't have inheritance. This makes a lot of basic C++ programming patterns unfit for Rust, and prevents 1:1 translation of C++ to Rust.
• Rust's generics may look like C++ templates, but they're not. Rust's macros behave more like C++ templates, and generics are closer to C++ concepts, but neither is a close match. C++ programmers are generally flabbergasted how hard is to make a function that takes any integer type in Rust.
• Even though Rust copied C++ moves, and has "RAII", the way these are used in practice ends up different due to having opposite defaults and different guarantees. Rust doesn't have constructors. Its closest equivalent of exceptions is for a different purpose. Rust's types are always movable, don't have meaningful addresses, can't reference own fields. Even C++'s std::string is hopelessly incompatible with Rust.
C++ has two string types, because of C legacy. Rust has two (and more) string types to express different modes of ownership. C++ is a complex language, because they keep adding more ways to initialize a variable. Rust has exactly one way. But Rust has many other features, mostly in its type system, to define thread-safety, memory-safety, and memory management in detail that is beyond what C++ can express. So "but they're both big" is glossing over all the reasons why.
However, C happens to be almost a clean subset of Rust. You can take a C program and translate it line by line to Rust. It won't be idiomatic, but may be easy to refactor into proper Rust. That's generally not true with C++, which requires rethinking everything from basic idioms and constructs to the overall architecture. This is why Rust struggles with GUI libraries, and the best-supported native toolkit is from C.
- zeroxfe 3y ago> However, C happens to be almost a clean subset of Rust. You can take a C program and translate it line by line to Rust. I can't see how that's possible, unless you litter your code with `unsafe` all over the place. Rust requires a lot of restructuring around ownership and borrowing to get your code to even compile.
- pornel 3y agoI've done it with a few libraries. They usually have defined ownership, but it's specified in the library's manual, not in the code. Even unusual patterns can generally be mapped to Cow or Option or worst case some custom smart pointer with minimal amount of unsafe. But very often merely converting pointers to & vs &mut vs Box as appropriate gets the job done. The most common sin is C libraries taking just a pointer and hoping for the best, instead of pointer+length for buffers (slices). But that's also a "local" problem you can fix by adding an extra argument, generally not a major redesign. Thread-safety tends to be worse to map, because C reasons about safety of function calls, while Rust about sharing of data types. So "it's safe to call foo unless option bar is set to -5" doesn't translate well.
- pjmlp 3y agoRust has traits inheritance.
- pornel 3y agoSibling comment also says "has interface inheritance with pretty much the same syntax", but this is another case where people see the same ASCII char and think it's the same feature, when it's so different. The A:B syntax is not inheritance, but a syntax sugar for 'A where Self:B' bound. The result is these remain separate traits without support for subtyping. dyn trait A:B can't be used where B is required, unless you have access to the concrete type and make a new vtable for B from scratch. There's WIP to fix that, but not here yet. The auto traits that look like subtyping are for built-in marker traits only. Lack of data inheritance is painful. There's no support for fields in traits. Getters/setters are problematic due to borrowing all of self instead of just the field. Traits can't have private or protected methods. Traits aren't inherent to the types, so you have to import both the type and the trait to use it. It's messy and makes interface docs confusingly fragmented. So Rust really really isn't an OOP language, even though you can put together an awkward-to-use imitation from a few ill-fitting features — but they use the same sigils as OO in C++!
- pjmlp 3y agoRust is OOP, regardless how many try to sell it as not, there are many ways to skin a cat. You can enjoy my Rust version of Raytracing on one weekend, then again maybe not. Just like being an FP language doesn't mean does it like Haskell. Many of which even predate Haskell's birthdate. Plenty of ACM, SIGPLAN, IEEE, and EUROCOOP papers on the matter, including a few ones from a certain Simon Peyton Jones.
- alchemio 3y agoC++ is the most important source inspiring Rust throughout its development. Rust devs just like to downplay that role. - Rust has interface inheritance with pretty much the same syntax - Rust’s generics are monomorphized, exactly like C++ templates. They also have the same syntax. The only difference is that Rust generics are trait bound. - Rust RAII is used exactly as it’s used in C++. Moves in Rust are destructive, while in C++ they are not. At the time where move semantics were proposed for C++ in the C++03 era, both types were proposed and the committee decided to go with non-destructive moves. - Scope resolution syntax is also a carryover from C++. When the words superset and subset are used in regards to C, C++ and Objective-C, it is quite a misunderstanding to describe C as a subset of Rust.
- pornel 3y agoRust is inspired by C++ the same way JavaScript was inspired by Scheme. Yeah, there are some borrowed concepts, but it's a different language.