Can't blame the languages???
Ted Neward has a post up on OO. He's got a lot of cynical thoughts today:
Languages like C++ and Smalltalk were going to enable a revolution in the industry: Object-orientation was going to make it easy to build complicated systems out of atomic parts, solve world hunger, bring about world peace and make us all rich. For quite a while there, if you didn't throw the term "object-oriented" into a conversation, you obviously weren't a hip developer or manager and therefore obviously weren't worth listening to.Ten years later, and we're still waiting for the object utopia promised us. It's not like we can blame the languages, either--several additional object-oriented languages, most notably Java, emerged over time, and still no utopia. Vendors even sought ways to put object-oriented extensions into other places, like the relational database (but this was only when object-oriented databases themselves failed to materialize in any large-scale way), to no avail. The promised "object marketplace" just never seemed to happen--certainly object-oriented frameworks (like MFC, OWL, and several other libraries) came about, but these weren't "objects", but basic technology-specific scaffolding for building more objects. Where was the "object palette"? Where were my "SavingsAccount" object and my "BankTeller" object and my "ArcadeGame" objects, that I could just reuse and extend as necessary? It's as if objects failed us somehow.
Let me disagree strongly with the "can't blame the languages" theory. C++ was and is a crappy way to do objects. It's a mixed metaphore language, neither fish nor fowl. Primitive data types get in the way of clean object models, and the lack of garbage collection gets in the way of decent object models. Then we have Java - it adds in gc, but still has primitive data types, and makes a few more horrible mistakes:
- Final classes
- No extension mechanism
Java is fundamentally broken from an OO perspective. I suppose one can do OO in it, but the language (and C development culture) sure don't help you move that way. Ted's just wrong - we can and should blame the languages.
Then he goes on this riff:
Even worse, the marketplace grew around a decidedly non-object-oriented technology. Starting with its 3.0 release, Visual Basic, the butt of programmer jokes, that "technology to keep journalism majors employed", that language that wasn't even object-oriented, for heaven's sake, saw a huge, multi-million dollar industry spring up almost overnight around selling "things" that could be dragged, dropped, and reused without hesitation. This was a language that was developed around BASIC, for crying out loud--no implementation inheritance, no pointers, no overloaded methods or even basic encapsulation. And yet, it was reaping the benefits of binary reuse left and right. It was like watching the dorky guy at the dance, the guy wearing the red-and-green plaid tuxedo, go home with the prom queen.
You can pretty much see the problem with the C language crowd and OO here - (and they call us Smalltalkers arrogant!) - pointers are part of OO? The syntax (Basic, in this case) is disqualifying? (Only curly brace languages may apply, apparently!).
And this:
GUI frameworks, like MFC, succeeded in capturing a significant portion of the complexity associated with building GUI applications, but not in the way objects were originally envisioned. We thought we could just inherit from a base class, thus reusing that base class' functionality, but found that when the next version of the framework shipped, everything broke for some reason.
Broke for some reason???? How's about lack of care for backwards compatibility on the part of the vendor? This has nothing to do with OO - more of a vendor culture issue, IMHO.
Ahh, now here come the not terribly well informed criticisms of Smalltalk:
The first problem, the idea that reuse was achieved via inheritance, was originally conceived out of experience with the only other serious object-oriented platform at the time, Smalltalk. In Smalltalk, all reuse was done through inheritance--if you wanted to make use of a class, you inherited it, and added whatever specialization, overriding, or new behavior desired. Unfortunately, while this works in a loosely-typed environment like Smalltalk, it doesn't work in a strongly-typed one like C++ or Java. What results is a nightmare scenario where the base classes in the hierarchy can rarely, if ever, be modified without breaking (usually in spectacular fashion) every single one of its implementation derivatives. This was commonly called the fragile base class, or FBC, problem. In the long run, it prevented successful evolution of base classes once released into wide use.
Yeesh, where to start. Loosely typed? Sigh.... How many times can we point out that C++ is loosely typed, while Smalltalk is strongly typed? People consistently mistake manifest typing for Strong typing. You would think a few core dumps along the casting path would have taught them, but no....
Then, the statement - "if you wanted to make use of a class, you inherited it, and added whatever specialization, overriding, or new behavior desired. Unfortunately, while this works in a loosely-typed environment like Smalltalk, it doesn't work in a strongly-typed one like C++ or Java". Hmm. Apparently, Ted's not seen class List in VW, or any of a number of other delegation examples. Sure, languages like Self make delegation easier. But it's used quite heavily in Smalltalk. Developers figured out a long time ago that deep inheritance trees tended to have issues - and it's not simply because of Manifest typing.
Regardless of the actual implementation or API of the collection class, it's a well-understood pattern that obtaining the items within the collection should be done through an alternative, separate object instance--an iterator. The iterator focuses on traversing the objects contained within the collection, and has implicit "deep" knowledge of the container's internals to enable this. And here we see the problem of reuse at an object level: these two objects make no sense without one another.Hmm. We don't have this separation in Smalltalk. Closures, anyone? And in case we thought the industry might be learning, C# has no closures either. To paraphrase the old riff on DOS vs. Unix - Here's a nickel kid - buy yourself a real OO implementation.
However, his riff on Component reuse makes sense:
Quietly alongside the object revolution, a second revolution was also taking place. Born out of the object revolution but focusing more on solving a different set of problems, the idea of building mostly-independent "things", called components, began to take shape. These would be "things" that were of larger granularity, completely self-contained and reusable without any sort of inheritance relationship. Microsoft's Component Object Model was one of the first technologies to embrace this idea completely, and was often criticized roundly for it: because COM focused on building components rather than objects, COM was often denigrated because it offered no mechanism for allowing implementation inheritance, a key cornerstone in "object-oriented" approaches. Unfortunately for the object purists, COM's viability got a huge boost from an unlikely source: Visual Basic. After demonstrating that the "VB control" concept was in fact a viably useful one (as witnessed by the market that sprang up after its 3.0 release), Visual Basic then took the step of effectively abandoning the 16-bit VBX format it created in 3.0, and moved to a 32-bit, COM-based OCX (Ole Control eXtension) format for VB 4.0. This in turn was simplified to create the ActiveX control, which could be either visible or invisible, and later embedded on an HTML page for downloading across a network.It's the same critique I used to make of PARTS - that individual widgets in a GUI were not really the right level for wiring. Same thing here - individual objects are not the right level for reuse either. We are starting to see some coarse grained reuse in some of the open source projects I'm associated with - BottomFeeder, TypeLess, and Pongo. In our case, it tends to be at the package (component) level.
Go read the whole thing - the component discussion at the end is interesting.

