With a good type system that includes traits, you almost never need virtual dispatching, as any Rust developer may tell.
With a good type system that includes traits, you almost never need virtual dispatching, as any Rust developer may tell.
Take the following example I have found on the net: https://play.rust-lang.org/?version=stable&mode=debug&editio...
In that example, both the bicycle and the car have the property `speed`. Imagine you have multiple types now that need to have the `speed` property. You would need to copy-paste the same code for each new type in order for you to be type safe.
Apparently it is called *Monomorphization*: https://cglab.ca/~abeinges/blah/rust-reuse-and-recycle/#mono...
From the article:
* But if I want a single queue to be able to handle different tasks, then it's not clear how that could be done with monomorphization alone. That's why it's called "mono"morphization. It's all about taking abstract implementations and creating instances that do one thing. *
Which was exactly what I was experimenting with: A single queue worker that can handle different cases. Honestly, it made Rust almost not worth it for me. Sadly, I was too deep to turn back so I wound up doing the whole thing in Rust. I have tons of copy-paste code. It is ugly and it is bothering me.
The need for something to solve the problems inheritance solves has been known in Rust for a long time. Mostly it's been motivated by the need to implement the HTML DOM, which is fundamentally an inheritance hierarchy, in Servo. There's a longstanding RFC about it:
https://github.com/rust-lang/rfcs/issues/349
Inheritance is one possible solution. There are others.
Another issue I have with it is perfectly described in this article: https://theta.eu.org/2021/03/08/async-rust-2.html
For what it's worth traits largely prevented copy and paste and where traits fail there are macros. The classic inheritance example you link to is a tiny percentage of my code and an orders of magnitude smaller time sink when compared to the code maintenance problems I faced in other languages.
True, but not that interesting? Sure we could have some Ruby :get_attrs magic or whatever.
fn id<T>(t: T) { }
fn main() {
id(String::from("foo"));
id(1_usize);
}
The Rust compiler will generate a method of `id` that works for both String and usize, so there will be two copies of the function with a slight variation in your binary. That process is called monomorphization.> Which was exactly what I was experimenting with: A single queue worker that can handle different cases. Honestly, it made Rust almost not worth it for me. Sadly, I was too deep to turn back so I wound up doing the whole thing in Rust. I have tons of copy-paste code. It is ugly and it is bothering me.
You can easily use generics, there is no reason to copy paste code like this
You can also do this:
struct Vehicle
{
speed: f32,
type: VehicleType
}
enum VehicleType
{
Car(...),
Bicycle(...)
}
Or this (although this is the least common): struct Vehicle
{
data: VehicleData
type: Box<dyn SpecificVehicle>
}
struct VehicleData
{
speed: f32,
}
trait SpecificVehicle
{
fn quack(&self, data: &VehicleData);
}
impl SpecificVehicle for Car {...}
impl SpecificVehicle for Bicycle {...}As you can see I also used a macro by example there to remove some of the duplicated code that you would otherwise have.
> You cannot compose types in Rust. You compose behaviors not types.
But I thought in OOP behaviour is type? (Or, IOW, type includes behaviour.) To me, judging only from this, it feels like Rust isn't quite OO... Is it perhaps just not quite finished yet?
Another aspect: That whole "Rust has something called 'monomorphization', which leads to lots of copy-pasting" reinforces that impression. Is this the same problem that C++ tries to overcome by the "select which inherited implementation to use" operator, and other languages by allowing inly single inheritance?
"Well, mmm, duh?", thought programmers of other languages.
"I've designed this project in Rust, following Rust-imposed design principles, and found monomorphism sufficient", said the Rust programmer.
"Well, mmm, duh?", thought programmers of other languages.
"I've designed this project in Python, using Python-style design and I've found that I did not need strictly typed functions", said the Python programmer.
"Well, mmm, duh?", thought programmers of other languages.
"I've designed this project in language X, which impose Y and as such I've found that you actually don't need Z", said the X programmer.
"Well, we got the picture already", said the HN reader.