"they aren't smarter or more sophisticated than they were before"
To be clear, I was not suggesting that more layers of abstraction reflect more sophisticated developers. Just that more layers require something in the language to help developers manage those layers without going insane.
There's a lot of wisdom in choosing a flatter approach when it makes sense.
In your opinion, what languages do have effective tools for managing high towers of abstraction? I'm genuinely curious, having spent many nights building ontologies.
C++ and Rust come to mind. C++ can certainly go awry, but it does seem to have the tools available, even if they might be hard to use. Rust still has a few things to prove, but things are looking fairly good. Both languages can express constraints (e.g. type constraints) so that you don't have to make too many assumptions, and you know when APIs change in subtle ways. And both languages use inlining heavily to get "zero cost abstractions".
I'll include ruby as well. It doesn't have a lot of "tools" per se, but if you're working on a nice codebase, it works out well even if using a lot of gems. Part of this is probably the unit testing/mocking, and part of it is that the code is just smaller. It does nothing to help you with performance though, so it can get really bad.
My experience with Java has not been great. I'm unconvinced that inheritance hierarchies are a good idea at all, or much of the other ceremony around Java-style OOP. Java uses JIT compilation, which can help with performance a lot.
If by "ontology" you mean "hierarchy", I'd caution you against that approach. Hierarchies enforce an order that is just not there in many cases. For instance, if you have an iPhone, would that be Hardware/Apple/iPhone or Apple/Hardware/iPhone? An iPhone is both Apple and Hardware, but there is no real order to those two -- yet if you try to put them in a hierarchy, then you must choose (and the choice will matter). I think interfaces/traits are much better. Both Go and Rust got this right.
To be clear, I was not suggesting that more layers of abstraction reflect more sophisticated developers. Just that more layers require something in the language to help developers manage those layers without going insane.
There's a lot of wisdom in choosing a flatter approach when it makes sense.