← Back to context

Comment by pornel

19 hours ago

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.

  • I've been writing Rust since 0.x versions.

    > C is their dad

    You can write "C with classes" in the "C/C++/Rust" language, and have users of all three tell you you're doing it wrong. The commonalities between them are mostly necessities of systems programming, FFI, and LLVM-style optimizations, but they all try to get there in different ways.

    > There are far more exotic languages out there. APL. Erlang. Forth

    Early Rust started as an Erlang clone, with task supervision trees and all (panics, lock poisoning, and the defunct UnwindSafe trait are vestigial features from that experiment).

    Rust has more in common with Ocaml than C or C++. It's not a C family language, it just took C-like syntax to avoid the stigma of being "exotic" like the languages that inspired it.

    Rust did copy move semantics from C++, but even that ended up being different enough to be incompatible with basic C++ design patterns. Rust chose to have only trivially movable types and guarantee absence of move constructors, so it can't even safely pass a C++ std::string.

    • > It's not a C family language, it just took C-like syntax to avoid the stigma of being "exotic" like the languages that inspired it.

      I agree that Rust has very conventional C-like syntax, but I'd go further and say it has fairly conventional C-like semantics too, at least in its current iteration. I think you could safely duck type Rust itself as a C-like. :)

      Strong agree that Rust has drawn great inspiration from the ML family by way of OCaml. Rust is a C-like with ML characteristics, which are its greatest quality, imho. On the other hand, I don't think there's much trace of Erlang left in Rust -- there's probably more Erlang in Go than Rust, and Go is squarely a C-like.

      I think it's fair to say that Rust started out more exotic than it is now, but perhaps all that safe, C-like syntax has led to convergent evolution towards other C-likes?

      > Rust did copy move semantics from C++, but even that ended up being different enough to be incompatible with basic C++ design patterns. Rust chose to have only trivially movable types and guarantee absence of move constructors, so it can't even safely pass a C++ std::string.

      Right, but compare all of that to Erlang's actor-based message passing, where mandatory immutability averts the need to move or lock anything at all, and I think it's clear why one would group Rust with C++, and not Erlang.