That depends on the job I want to do. But generally my selection is something like this.
Preferred backend language, Rust, since that have the least runtime errors, thanks to its strong typing and the great error handling. But I also use Go if it have better libs for what I do, or Java for situations where that is more suitable.
When you compare “idea to deployment” speed, a dynamic language will always win. However, much of this win is due to a dynamic language will let you deploy with a lot of bugs. So, you will then have to spend lot of time fixing production issues. Rust will force you to fix most of these issues before you can deploy, hence it feels slower in this aspect. I previously worked for 10 years with a huge perl code base, and I trade the deployment speed for stability in production any time.
Traits are similar to an interface, but with some differences. Here is a comparison with Java interfaces https://stackoverflow.com/a/69485860
If you look at Rust for example, then you specify the Traits instead. So, you could define a trait that defines the properties for birth, another to define if the animal have a beak, and another one to define the number and type of legs. The each animal implement these traits, which then properly can define a duck, cat and a platypus.
But even there a TcpStream, a FileStream and a StringStream might have quite differen behaviour, since they all abstract very different things. So, even this simple example may fall apart very fast if you need to care about those. I’m not saying that Inheritance is always bad, but it is quite rigid and might cause problems in a large codebase if you suddenly run in to the corner cases where the assumptions the abstraction is based upon is no longer upheld.
The core problem I see with Inheritance is that the abstractions tend to fall apart and no longer be true. Lets use the Animal example. It is easy, when you have Animal -> Cat and Animal -> Dog. But as soon as we become more specific like Animal -> Mammal -> Cat, Animal -> Fish -> Hammerhead Shark, Animal -> Bird -> Bald eagle, we risk of getting in trouble. Because now for all purposes we assume things about the Fish, Birds and Mammals, like fish is in the sea and mammals are live on land. We know that this is not strictly true, but for everything we need it works. Later we need to handle a dolphin… should that be a fish, or do we need to restructure the whole program. If we treat it like a fish, then we might be even deeper in trouble later if we would need to handle birth. And even if we restructure our program to be correct to handle birth, we might stil forget that some mammals lay eggs like the Platypus, so then things break again if we need to handle that. We tend to see Inheritance as a rigid fact based structure, but the core problem is that it is just a bunch of assumptions we dictate in a very rigid way that is hard to change.
Composition have no problem with specifying the platypus as a mammal that lays eggs and have a beak.
I think you are getting things backwards… Learning to write rust might be hard, if you are not used to typed languages or languages with explicit memory management with stack/heap separation. However, writing rust is not hard. It might take slightly longer in the coding phase, since you are forced to do things correct, you need to handle errors and are not allowed to share data between threads in dangerous ways aso. But that makes the resulting software a lot better, which means that the testing and support is a lot less. So, if anything, the net result of writing software in rust is that it is easier, since you are not allowed to shoot your self in the foot over and over again.
And remember, that every time rust is making your life difficult, you might have introduced a subtle bug in another language.
Tested to search for a stomp rust crate and got horrible results. So, I guess that you should test the different search engines with your use case and see which one fits that.