Windows, iOS, Android, Photoshop, Excel, Chrome - these are complex products that use object-oriented programming. They exist and work well. They have shipped many new features over the years.
Windows, iOS, Android, Photoshop, Excel, Chrome - these are complex products that use object-oriented programming. They exist and work well. They have shipped many new features over the years.
I would argue that the examples you give don't work well (Windows, Android, Chrome, later versions of iOS). They get worse and worse over time. Even if they start out with a good design, it turns to crap eventually.
Just because a piece of software is used by billions doesn't mean that it is well written.
This kind of thinking got us Teams and Slack.
Given that, the definition of yours does not provide much to discern between paradigms.
But we can compare complexity of logic of different systems and I provided two examples of that. We can even discuss some ordering between different systems.
For example, contemporary type system that is powerful enough (not even dependently typed) can model class hierarchy, it is a no big deal [1] from, at least, 2005. So classes are, in some sense, less general than System F that is used above. They also more specific, whether it is good or not.
[1] https://www.cs.tufts.edu/comp/150FP/archive/oleg-kiselyov/ov...
But in System F in [1] you can have several parallel class hierarchies, without requiring anything else from the system.
The same goes to other things like "escape hatches".
System with dynamic types cannot prevent (runtime) errors that can be prevented by a system with static types. It is just not possible to have reasonable description of a system without certain kinds of (runtime) errors without reimplementing many things from system with static type checking. On the other side, in system with static types it is quite possible to have over-encompassing type that represents all dynamic values one needs.
So, systems with static type checking are, in some sense, more general than systems with dynamic type systems. And, of course, systems with dynamic types are more specific, whether it is good or not.
That's the whole point. "Reasonable" is not synonymous with "optimal", so we ought to expect that there would be multiple reasonable paradigms to choose between. Which programming paradigm you choose is very rarely the largest factor in the success or failure of your product.
You can solve any problem by throwing more money (millions of developers). The money is the largest factor in the success or failure of the product of... yours?
When something is constantly true for all objects in the scope of the domain, it is considered tautology and should be dropped from the discussion as it adds nothing.
If reasonableness is equally meaaningless, we can drop it.
Instead, we can look at other properties of programming paradigms.