sorry, but this is no true Scotsman fallacy. All these "bad implementations" is OOP, real OOP, not some idealized ephemeral non-existent Avalon. If an idea easily and more frequently than not lands itself to the bad implementations then there is something wrong with the idea. (I happen to come from a country which was pursuing what was looking like a pretty good idea - communism - which has got a lot of bashing during recent decades, due to "bad implementations" i guess, and as result it was critically rethought and now we know what it is not a good idea really)
Person --> Full Time Employee --> Manager
Person --> Contract Employee
Without inheritance assuming that salary calculation is the only thing which differentiates them.
Person HAS A IEmploymentRelationship
ContractEmployment IMPLEMENTS IEmploymentRelationship
FullTimeEmployment IMPLEMENTS IEmploymentRelationship
FullTimeEmployment HAS A IDirectReport
Manager HAS A Person
Manager IMPLEMENTS IDirectReport
And then salary() is a polymorphic function declared by the IEmploymentRelationship interface, where FullTimeEmployment instances use the manager somehow, and ContractEmployment doesn't.You can even put some sugar on that by having a salary() function on Person that calls the salary() function on its IEmploymentRelationship—but I wouldn't, for the same reason I wouldn't denormalize a relational database.
Those are not Smalltalk's definitions -- even though I think you're right on about Alan Kay's original inspiration -- and confusion can arise if we redefine terms.
So if you want to embrace high performance (and concurrent), go message passing. Alan Kay's favor of late binding does not help performance, as method lookup at run-time dominates the cost then, but the fast systems are early bound, i.e. typed.
Of course, you are probably referring to NUMA, but people still actually use that.
Pure OO isn't very much desired in the HPC world, but then neither is pure FP.
[[myView onMainThread] setNeedsDisplay:YES];
result = [[someObject future] someMessage:arg];
combined = [[prefixes collect] stringByAppendingString:[suffixes each]];
The reason this is easy in Objective-C is because its brand of message passing is just (barely) powerful enough to qualify as message passing. In fact, if you squint just a little, you can see it as fully reified message passing with the common-case (a synchronous method is invoked) optimized.[1] http://en.wikipedia.org/wiki/Higher_order_message
[2] http://www.metaobject.com/papers/Higher_Order_Messaging_OOPS...
In fact, the origins of OOP are basically what we would now call microservice architecture (CSP-inspired languages like Go being a specialisation of this). Each service can be as stateless or as stateful as it needs to be (without shared state) and services should be loosely coupled.
That's quite different to most large-scale OOP architectures, but it is possible to code in that style in any OOP language.
Heavy reliance on inheritance for code reuse is a whole problem class in itself that again has little to do with OOP and lots to do with the influence of C++.