Comment by nicoburns
1 day ago
A mitigating factor in this case is the C++ and Rust are both multi-paradigm languages. You can quite reasonably represent most C++ patterns in Rust, even if it might not be quite how you'd write Rust in the first place.
I disagree. You can't even create simple C++ inheritance examples because you don't have data inheritance. So basically classical OOP is out of the window.
That's the biggest difference to C++ and most mainstream languages, you simply can't do OOP (which in my books is a good thing) and it forces you more towards traits and composition.
In addition, C++ and Rust are very, very similar languages. Almost everything in C++ translates easily, including low level stuff and template shenanigans. There's only a few "oh shit there's no analog" things, like template specialization or virtual inheritance.
Out of all the languages rust takes inspiration from, id rank C++ at the top of the list.
Strong disagree. Rust copied C++ syntax to avoid looking weird to C++ programmers, but the similarity is skin deep. C can be tamed, because it's mostly a subset of Rust, but C++ idioms are a death from papercuts.
OOP, weakly-typed templates, and mutable aliasing create impedance mismatch in almost every C++ API.
Rust doesn't have data inheritance, and what looks like interface inheritance is merely extra requirements in a flat list of traits, so subclassing won't behave like C++ APIs expect. When you translate a class hierarchy to Rust, it needs lots of crutches which make it weird, boilerplatey, and tedious to use. There's no good recipe for OOP hierarchy in Rust, because the idioms are so different. The mismatch feels like writing an ORM.
For some C++ APIs mutability and circular references can be a pain too. Rust works well with DAG data structures and clear mostly-immutable data flow. Objects with some "parent" pointer are common in C++, but Rust sees them as potentially dangling, with shared mutable state, and requires much heavier control of them. It can be done, but it's ugly. Idiomatic Rust designs go to great lengths to avoid it unless necessary, but C++ APIs can have the extra pointers "for convenience".
There's a reason why Rust doesn't have typical GUI libraries - an arbitrary web of references between widgets and event handlers make it ugly in Rust, and that's on top of a view class inheritance.
C++ templates sit very uncomfortably between Rust's macros (duck typed) and Rust's generics (strictly typed at point of declaration).
C++ templates almost always are a mix of types they're attached to and some duck-typing in their expansion.
Rust's generics do not allow any duck typing at all. This makes translation of even a tiny bit clever C++ templates a chore. There's no specialization. No way to deal with SFINAE and such.
Rust macros have flexibility for all the syntax shenanigans (and even similarly bad errors at instantiation time), but macros can't see any types. Idiomatic Rust has very deliberate division between traits (usually much simpler and smaller in scope), macros and proc macros/derives. Splitting C++ templates like that can be a major redesign.
Rust's OOP model fits perfectly into COM, WinRT, which is also OOP from CS point of view, and known for decades.
See Component Software: Beyond Object-Oriented Programming, first edition 2002.
Also the way Microsoft is implementing their windows-rs crate, and WDK for Rust.
As someone who's worked in both C++ and Rust, they're deeply similar languages. There are far more exotic languages out there. APL. Erlang. Forth.
In the grander scheme of things, Java and C# are literally the same language, Rust and C++ are twins, C is their dad, Forth is the owl staring through the dining room window, and Erlang is an alien spaceship passing over the house.
2 replies →