90% of the time this is dumb overhead, but 10% of the time it found a bug in some edge case, so I learned to appreciate it as a tough teacher, and my designs got better for it.
Sounds kind of like Stockholm syndrome
Seriously, I sometimes wonder what is wrong with the whole field of software development.
What is better about them?
Code here: https://github.com/prisma/prisma-engines/tree/main/libs%2Fda...
It serializes better, it's memory safe, it can be much faster in performance terms, you can get better memory usage if you're holding a lot of "pointers" because the indexes don't need to be 64 bits.
I just can't help but wonder what it means for that paradigm, when the most popular answer to "how do I model my entities in safe Rust" is basically "backdoor the safety".
If it was (2), it sounds like you made it work without unsafe code? Can you share some code?
I've tried some basic OOP.
Fields from the base class need to be redefined in each child, and making shared methods private require an ugly workaround. Both concepts are very basic OOP concepts, not advanced or inherently/tendentially dangerous, and the results is that even basic Rust OOP requires a lot of boilerplate. It's workaroundable with macros if one wants, although they have some limitations, and I guess this is the reason why the macro approach is not widespread.
Some devs use composition to emulate it, but the result is another form of boilerplate (very noisy builder patterns).
Regarding "non-basic" OOP features, I remember that Rust GUI framework programmers uniformly complain about Rust not being appropriate to translate the OOP hierarchies typically used in GUI frameworks, so the gap is significant (this is not inherently bad; not supporting OOP can be a respectable choice, but matter of factually, this does create a gap in some cases).
Now how that is done is practice, can be done in various ways.
Class inheritance, which is what many think of.
Interface inheritance or conformance, which is available in many languages via traits, patterns, data classes, functors, or other names, and OS ABIs like COM.
Prototype inheritance, clone a instance and monkey patch in place (like SELF)
Via composition and delegation for not handled messages.
Then many languages offer a combination of those approaches.
struct B {
a: A
}I mostly use OOP when I have a bunch of Foos and Bars, and want to treat them differently in some places. Instead of having ifs in each function, I use inheritance, and override the methods that I want to treat differently. It's mostly about heterogenous containers and avoiding explicit ifs. When you use it that way, it's safe and convenient and I've never ran into the fragile base class problem or other typical issues.
I've seen it being repeated ad nauseam without any concrete backing.
I mean it has some OOP concepts. But it's mostly in traits. Saying Rust is OOP is a bit like saying Chimera is a Goat.
Anyone that tried to use OOP in Rust, knows it's next to impossible.
Otherwise you end up with Haskell is an OOP language.
Just like being an FP language isn't "like Haskell does it", when I learned FP, Haskell didn't even exist.
Try to express Eiffel, CLOS, SELF or BETA in Java.
By the way, here is One Weekend Raytracing in Rust, perfectly using OOP with dynamic dispatch and interfaces (sorry traits).
Counter example: Html5 DOM.
A graph representation of nodes based on JavaScript object model?
Fine, https://rustwasm.github.io/docs/wasm-bindgen/examples/dom.ht...
It's a brittle simulation of Inheritance. To transform a saying "Just because you can write Ada in C, doesn't make C Ada".
How to prove.
Assume that we add struct inheritance to Rust (it looks similar to JS) - call it RustInh.
Does adding inheritance to Rust increase expressive power? If yes, then right now Rust can't express OOP concept as inheritance. I.e. is there a C[RustInh] = C[Rust].
And way to prove it is to look at Deref anti-patterns https://github.com/rust-unofficial/patterns/blob/main/anti_p...
I'm still not sure that fully captures my intuition of easy to write.
That doesn't even make sense on its face. There are things which are trivially expressible in Smalltalk and I'm not sure even possible to wrangle in Java.
I do wonder whether this is as much of a problem as people think. Most of the time it only becomes a problem when people start doing stupid things to override the parent instead of refactoring a new class out from under it.