As I've become more experienced over the years I've come to believe that the prolification of patterns to "fix" oop problems (dependency injection, immutability, builder patterns, events etc etc) are a symptom of inherent flaws in the object oriented model.
It feels like we're bending over backwards to fix a model that promotes lots of problematic designs while not doing much for resolving them (or supporting basic things like concurrency/parallelism). We can never predict all possible problems, or predict the future so no language can be "perfect", but a language could inherently be more agile and flexible. I wish I could say what a better model would be. I'd hazard a guess that its something more based on composition and functional programming than inheritance and classes. Perhaps even metaprogramming and/or code generation
For now it seems OOP is the worst paradigm for programming, except all other paradigms of programming
It's a good, if fairly old [1] insight. The fact is, there are two kinds of patterns: architectural patterns (e.g. "message bus", "web service", etc.) and there are language deficiency patterns (e.g. factory, double dispatch/visitor, etc.). A good way to gauge the power of a language is to see how many of these patterns you need.
For example, when I was exposed to Smalltalk I fell in love with it. So many of the patterns I was used to needing were not necessarily there. That's because Smalltalk is more expressively powerful than, say, Java. You see this directly in the GoF patterns book as several of the patterns only provide C++ code and say "Smalltalk doesn't need this as it does X".
Eventually, though, I begin to see that pg was right and single dispatch is a subset (in this case; inferior) of generic functions. The issue was double dispatch. Smalltalk needs it, Lisp doesn't. I never have to write boring double dispatch wiring in Lisp because of how generic functions work.
So I don't think it's OO itself that is flawed (though it's not as a big a deal as it's made out to be. It's a form of code organization, specifically global variable demarcation and code reuse), but rather many OO languages that are weak enough to require programmers to hand-code out these common patterns instead of either providing it in the language or providing a powerful enough language to let us solve it once.
Agreed. I'll go ahead and burn the karma on an overwrought historical analogy right now:
C++ did to object-oriented languages in the 90s what the Church did to Europe in the medieval period. Thankfully functional languages (the Islamic world) preserved a lot of knowledge through that period so that it can now be re-introduced.
I agree that single dispatch seems to be a pretty obvious problem with most oop languages, if you have a method that has two different types as parameters, on which do it belong? Take a pick and hold your breath... or do some unwieldy manager class :) Smalltalk and Lisp seems (zealously) loved by many, and it's easy to like the simple elegance of languages like that.
For me they always felt wee bit too messy and academically oriented. I want a language that reads more like a book and less like a formula, perhaps that's just me :)
This problem is easily resolved by noting that you think the method has to 'belong' to one type or another instead of exist as a first class object of its own. In practice this was done first in Lisp (the 'generic function' works better with typical Lisp environments than endless (send object message) calls, in particular with functions like map), and then the fact that the generic function treated one and only one argument specifically was noticed. From here we get multiple dispatch in a very natural way, a concept that is quite awkward in a language like Smalltalk.
The concept is quite awkward in any single dispatch language. The biggest WTF ever is Racket adding single dispatch OO! You actually have to say (send object 'message).
> I want a language that reads more like a book and less like a formula, perhaps that's just me :)
Perhaps you shouldn't look so much for a new language, but rather a new way of using the language. Have a look at http://www.literateprogramming.com/adventure.pdf, a showcase of literate programming using the example of the venerable Colossal Cave Adventure.
What's the alternative though? The minute you try to treat any group of data in a general way this problem arises. The minute you publish any kind of interface you've essentially signed a contract with all client code.
All the common solutions to this problem (structural typing, COM-style versioned interfaces etc) create problems of their own. I think it's just a genuinely hard problem.
Some day there'll probably be a nextgen language that addresses at least some of these issues. One way to resolve some of them today however is code generation.
While not appropriate to all kinds of solution I've had some success with building solutions, especially "enterprise solutions", where you model the problem descriptively (in say xml) and then generate the appropriate code.
This way you can glue together "architecture" code with "meat code", (ie substantial methods) and have the agility to refactor and regenerate. The bulk of the code is often some kind of yak pattern shaving so you can save quite a lot of time.
You're basically designing your own DSL (Domain Specific Language) and then writing the "parser/compiler"
Beat me to this but I like the objective C approach: You can save lots of specialized classes by extending existing ones with categories. And instead of a rigid class structure you usually check the availability of properties at runtime. It might be more verbose and in general more code but the code you have can be quickly adapted and is quite stable. I'd love objective c to become more multiplatform (which is of course the major downside for now).
It feels like we're bending over backwards to fix a model that promotes lots of problematic designs while not doing much for resolving them (or supporting basic things like concurrency/parallelism). We can never predict all possible problems, or predict the future so no language can be "perfect", but a language could inherently be more agile and flexible. I wish I could say what a better model would be. I'd hazard a guess that its something more based on composition and functional programming than inheritance and classes. Perhaps even metaprogramming and/or code generation
For now it seems OOP is the worst paradigm for programming, except all other paradigms of programming