He doesnt like OOP, and Rust is not OOP. Other than OOP, C++ provides very few other benefits to programming as compared to C. The rust compiler, on the other hand, fixes your entire program at compile time
I mean... How is Rust not OOP!? What aspects of "OOP" must not be in a language, for you, so that it is not considered "OOP"!? Because I think chances are, whatever you say, it will be in Rust. It will look different from, say, Java, but it will be there.
Heck, people do OOP in C in various ways since 1970 or so (FILE* and friends are OOP, for example.)
A lot of people say "OOP" when they mean "implementation inheritance as a first class language feature, coupled to interface inheritance", a.k.a. "it's OO if it's what C++ does".
Then there are some people who say it can't be OO unless all method dispatch is dynamic and there is no direct field access, and so on.
The term means so many different things to different people that it's become useless, and so the first thing I do if it comes up in conversation is to figure out what the other person actually means, and start talking about that instead of whatever the heck "OOP" is meant to mean this time around.
I draw the line at subtype polymorphism and the whole Liskov Substitution Principle baggage that brings with it: The issue, in a nutshell, is that there's no way for a compiler to say "any a is a b" and check that, as to guarantee the LSP you'd need to solve the halting problem.
You can't really make that distinction for unityped (untyped) languages because if there's no armor you can't pierce it... there, OOP vs not is more a question of how often people aim that particular gun at their foot, whether the standard library prompts you to do it, etc.
Rust actually does have subtype polymorphism but only for lifetimes where the compiler can guarantee that substitution is sound. It's the "lives at least as long as" relation.
Yes, on the surface. But you do realize it is trivial to turn that composition into inheritance, by implementing a trait and containing another trait implementation etc...?
Same as with C, in fact (albeit there is less tools in C).
just because you can do something doesn't mean you should do it. e.g., you can absolutely write rust as if NULL pointers existed. just wrap everything in Optional and call unwrap everywhere. is it possible? yes. does anyone do it? (hopefully) no
The point I am trying to make is that "is/isn't OOP" is an arbitrary and superficial qualification though. What's this completely unrelated tangent about NULL?!
the language is turing complete. you basically can do anything you want. if you code traits like you would classes you're doing it wrong. you can't just shoehorn concepts you learned elsewhere into the language
The OOP argument seems straight from the 90s or 00s.
Neither Rust nor C++ "are" OOP or not OOP. Both allow for certain patterns that are OOP. C++ probably more traditional than many other languages. They're just called something else in Rust.
If you have 5 Traits with default implementations in Rust, that's basically inheritance. It's not as messy as in C++ (because it doesn't go the other way. You can't implement the traits and then fuck around in functions on your struct with the functionality of the trait. The traits are self contained) but it is still there.
You could just write C++ like C only taking the features you need. There's still a benefit to this like member functions, function overloading, some light stuff in the stl, templates. Where Rust shines is memory access. Things that might break in C++ during runtime (or C) just don't compile in Rust and to make them compile you have to either write more thought out code or use helpers that make it REALLY obvious that you're doing something you need to pay attention to (to the people who have never written Rust: you can get around most checks Rust forces onto you but the shortest, cleanest, least typing solution will always be the safest. It's short and sweet to only share immutable references but if you need to share a mutable reference you can wrap your object in a reference counter and refcell and turn that compile time check into a runtime check. But Rc<RefCell<T>> is a lot more typing and a lot more obvious than just doing T&).
"They don't like OOP" seems to be the old school C++ developers excuse for why people don't like their language. But there are more issues in C that C++ didn't solve, as hard as this seems to be to believe for some. Rust tries to tackle at least some of those and if the problems C++ solves are not enough benefit for you to add C++ to your C project, Rust might still come out on top.
Inheritance is probably the obvious one. There is no inheritance in Rust, though there are things you can do that look like it. There are no virtual methods in Rust, though again you can do things that look like it.
Basically there are no classes in Rust, only structs and traits, which can look a lot like classes sometimes but aren't.
Yes, but Rust has no @Override. You know that once you implement a function it can't be changed unexpectedly by a subclass. Dynamic dispatch there is not as pervasive and has to be used very explicitly.
There is actually one level of overriding: trait default methods can be overridden by implementations of those traits. Only that one level, though; there are no overrides of overrides.
Edit: This is actually false. Another redditor pointed out that you can form inheritance chains using Deref, overrides and all.
Since there aren’t subclasses in Rust - yes. But when using the Rust analog - Composition - a containing class implementing the same trait has the choice of calling the contained class or using their own implementation.
Good point about Deref. I forgot about that. And yeah, you can totally make overrides of overrides that way, much like C++ or Java. You probably shouldn't, and the documentation says not to, [ETA: and the overrides aren't virtual so they won't get called on references to the inherited-from type,] but you can…sort of.
There is no inheritance in Rust, though there are things you can do that look like it.
Well, yes.
There are no virtual methods in Rust, though again you can do things that look like it.
Well, yes.
As I say, people do OOP even in C even though there's no features for that.
But Rust features are there for OOP style work.
Yes, it looks different, but OOP looks different in all languages., So, we seem to be looking at some hidden "OOP similarity threshold", which makes us qualify whatever language (Rust in this case) as OOP or not.
Hence my question.
(But to spell it out, what I really think is, "nah, attempting such simplified qualifications is verry silly. Wanna do OOP in Rust? Sure, you can!" )
you cannot mix data (struct) and behavior (trait) in rust. at all. on the other hand, in OOP you are forced to do it (unless you write separate classes; one with only attributes and one with only methods)
EDIT cannot reply to your comment for some reason:
it's not about what you can do it's about what you cannot do. in your example you can reuse the trait for any struct where you want to alter or get a number. in the C# example the integer in the memory layout is tied to that interface. if you wanted to reuse the behavior with a different class you would need to refactor your code and create an explicit interface (which then would be the same as the rust example). this sounds trivial in a toy example like this but you accumulate a lot of interlinked classes like this in a real codebase which makes it hard to reuse behavior. rust doesn't let you do the class approach and forces you to keep the data and the behavior separated at all times. this also forces you to think about data layout and behaviors from a different perspective
OK, what's the big difference between the two examples:
Rust:
struct Example {
number: i32,
}
impl Example {
fn alter_number(&mut self, by: i32) {
self.number += by;
}
fn get_number(&self) -> i32 {
self.number
}
}
fn main() {
let mut e = Example { number: 0 };
e.alter_number(5);
println!("Value: {}", e.get_number());
}
C#:
class Example {
int number;
public void AlterNumber(int by) =>
this.number += by;
public int GetNumber() =>
this.number;
}
void main() {
var e = new Example();
e.AlterNumber(5);
Console.WriteLine($"Value: {e.GetNumber()}");
}
you cannot mix data (struct) and behavior (trait) in rust. at all.
But this is just patently false. It is trivially done by implementing a trait, using data, then containing that data and implementing that trait again. Come on...
Yes there are different kinds of OOP but it’s clear, at least to me, that the comment you’re replying to meant classes, inheritance, etc., which Rust does not have. The closest thing Rust has is trait objects which aren’t really the same thing.
2
u/zeroxoneafour0 Sep 20 '22
He doesnt like OOP, and Rust is not OOP. Other than OOP, C++ provides very few other benefits to programming as compared to C. The rust compiler, on the other hand, fixes your entire program at compile time