> 90+% of programmers aren't even capable of doing object-oriented programming

Similar to other takes I've seen in this thread. But isn't it flawed to talk about being "capable of object-oriented programming" when object-oriented programming is itself an ill-defined, flawed idea? (I'm talking C++/Java/C#/textbook OO, not Smalltalk.) I spend a majority of my time in C#, and I'm not really sure I'm doing object-oriented programming either. Learning curves are never linear, but if it were, the curve for OO in C# would look something like:

Level 0: God-classes, god-methods. Puts the entire program in the "Main" method.

Level 1: Most of the logic is in "Main" or other static methods, with some working, mutable data stored in classes. No inheritance.

Level 2: Logic and state are starting to get distributed between classes, but lumpily -- some classes are thousands of lines long and others are anemic. Inheritance is used, badly, as a way to avoid copy/pasting code. Short-sighted inheritance based on superficial similarities, like "Dog : Animal". No clear separation of responsibilities, but "private" is starting to make an appearance. If design patterns are here, they're used arbitrarily. Still lots of mutability around. This is "OO Programming" as taught in early textbooks. It's bad.

Level 3: Methods and classes are starting to ask for contracts/abstractions instead of implementations. Inheritance hierarchies are getting smaller, include abstract classes, and are starting to be organized by need and functionality, rather than by superficial similarity; things like "TextNode : Node". Classes are clearly articulating their public surface vs. private details, with logic behind which is which. Generics are used, but mostly just with the built-in libraries (e.g. IEnumerable<T>). Design patterns are used correctly. Mutability is still everywhere. If interfaces are used, it's in that superficial enterprisey way that makes people hate interfaces: "Foo : IFoo", "Bar : IBar", for no discernable reason. This is "OO Programming" as taught in higher-level textbooks.

Level 4: No more "Dog : Animal". If inheritance is used at all, it's 1 layer deep (not counting Object), and the top layer is abstract. Code de-duplication is done via composition, not inheritance. Fluent/LINQ methods like .Select() [map] and .Where() [filter] have mostly replaced explicit loops. A large percentage of the code is "library" code -- new data structures and services for downstream use. Generics are everywhere, and not just with standard-library classes. Interfaces are defined by the needs of their consumers, not by their implementations -- you may not even see an implementation of an interface in the same project it's defined (this is a code-fragrance; a good smell!). Liberal use of Func<> and Action<> has eliminated almost all of the explicit design patterns and superficial inheritance that used to exist. Mutable state is starting to be contained and managed, perhaps via reactive programming or by limiting the sharing of mutable objects. This doesn't look much like OO as taught in textbooks.

Level 5: Almost all code is library ("upstream") code, with a clear, acyclic dependency graph. Inheritance is virtually absent; an abstract class may show up occasionally, but only because it hasn't been replaced with something better yet. Most code is declarative using fluent/functional-style methods on immutable data structures, like .Select() and .Where(). Where Level 4 may have abandoned that style at the limit of the "out of the box" data structures, Level 5 just writes their own immutable fluent/functional data structures when they need to. This means heavy use of interfaces, Func, and generics, including co- and contra-variance. It also means adapting ideas from the functional world, such as Monoids and the "monadic style" (but not an explicit Monad type, both due to the lack of higher-kinded types and due to the fact that Monad is a red-herring abstraction that is not useful on its own). Most code looks like it's written in a mini domain-specific language, whose output is not a result, but a plan (i.e. lots of lazy evaluation, but with sensible domain-specific data structures, not with raw language elements like LISP). Data is largely organized via relational concepts (see: Out of the Tar Pit), regardless of the underlying storage layer. Identity and state are separated. Data and function blend seamlessly. Mutability is almost exclusively relegated to the internals of an algorithm, mostly in said data structures. Virtually no mutable state is shared unless it's intrinsically necessary. If it is necessary, it's tightly controlled via reactive programming or something similar. A few performance-critical loops look almost like C, with their own memory models, bit twiddling, and other optimizations, but these are completely internal, private details, well commented and thoroughly tested. This looks nothing like OO Programming as taught in textbooks. It looks a lot more like functional programming (with some procedural sprinkled in) than OO.

If there's a Level 6, I'm not there yet, nor have I seen it (or known what I was looking at if I did).

So when I see someone say "programmers aren't doing OO programming", I don't know what that means. Only Levels 2 and 3 above look much like "object-oriented programming". If nobody told you C# was supposedly an "object-oriented language", and all you saw was Level 5 code, would you know OO was supposed to be the overriding paradigm?

Are people avoiding OO programming because they can't do it, or because they evolved past it? To someone stuck at Level 3, Level 5 code might look unnecessary, overly complicated, whatever. It might look like code written by someone who doesn't know how to do OO.