Hi all Smalltalkers! Only cross posting to squeak and pharo (communities I know), because this turned into a long post. But try reading it - I hope it is both fun and perhaps interesting. :) On 02/11/2012 01:21 PM, Janko Mivšek wrote:
Hi guys,
Again one interesting topic for this weekend to discuss. David Nolen, a Lisp and JavaScript guy posted in his blog an article titled Illiterate Programming [1] where he said:
"...Yet I think Smalltalk still fundamentally failed (remember this is a programming language originally designed to scale from children to adults) because *Objects are really hard* and no-one really understands to this day how to do them right...."
As Hernan pointed out - it is programming that is hard, not *objects* per se. While that is true, one can of course still reflect on the aspects of OO and why people *perceive* it as hard. SIDENOTE: As Milan wrote later in the thread - the patterns movement that Kent Beck started together with the Gang of Four led to the creation of TONS of books fully packed with OO designs in various domains. So yes, there is an *abundance* of books on OO design to find *iff* one goes looking for it.
He links to Alan Kay post [2] back in 1998 where he talks about problems with inheritance:
"Here are a few problems in the naive inheritance systems we use today: confusions of Taxonomy and Parentage, of Specialization and Refinement, of Parts and Wholes, of Semantics and Pragmatics..."
Of all OO mechanisms most agree that inheritance is the one that gets abused the most... if we disregard the "abuse" one can find in so called OO code that stems from it not being OO at all :) Alan writes "confusions" and I suspect he carefully avoids saying one is wrong and the other is right, because its not that simple. Truth is one can use inheritance differently - as long as it makes your life better it can't really be argued to be "wrong". :) I think most OO developers goes through some "ladder of enlightenment" going something like this: 0. You really have no clue and tend to confuse composition "parts and whole" with inheritance. You just create a mess. Perhaps you avoid this mess by reading a book or attending an OO course, but hey, who does that in 2012? ;). But let's say you *do* read a book - proceed to level 1... 1. You get all into Animals and other "inheritance" examples mirroring the real world. Perhaps you get totally sucked into the "mirror the real world"-idea. Thus, you try desperately to find "ISA" relations among the domain objects and use those for inheritance, without really thinking *why* that is a good idea. And sure, it often gets it fairly right so it's a huge step forward. But let's pretend you now have coded quite a bit and thus proceeds to level 2 :) 2. Specialization. After some time you start to understand polymorphism and the substitution principle etc, so instead of blindly testing if "A isa B" sounds right in your ears you start thinking in terms of generalisation and specialization. And you see objects in your head. You talk about them as if they are concrete and you can hold them in your hand etc. Perhaps you even draw them on whiteboards and envision them in different scenarios "talking to each other". If you use a statically typed language this is where your road stops :). You end up writing fairly good code, but your inheritance will probably be totally focused on enabling polymorphism between objects, which of course is not all bad. But hey, after a few years of Smalltalking - proceed to level 3. 3. As a seasoned Smalltalker you eventually come down from your "OO rush" and realize that... hey, wait a minute! Polymorphism is not *tied* to class inheritance (unless you are trapped in some static type system). In fact, you realize that class inheritance in Smalltalk is "merely" a nice way of reducing the redundancy of code by creating dependencies between separate abstractions of code. This realization enables you to use inheritance in a more liberal fashion - which probably means you tend to use it *less*. And instead you tend to "add more objects" and use composition of objects more and more, relying on brittle deep hierarchies of inheritance less and less. SIDENOTE: A really cool example of how powerful object composition is: PetitParser by Lukas. For years we have been creating parsers by generating code from specifications and suddenly Lukas decides that hey, why not instead *compose* a parser from ...objects? It is so obvious in retrospect, but the result is a tremendously nicer and more powerful way of constructing parsers. You also conclude that while you *can* reuse behaviors and compose behaviors using inheritance you are also aware that inheritance creates a life cycle *dependency* between classes that you *may* or *may not* want to have. Class inheritance is a brittle relation. Thus, even if class A *can* inherit from B, you might decide not to - because you anticipate that the development lineage will diverge, or perhaps you have no control over A (library? other developer? bad code?), and you do not want that dependency. But the up side is that sometimes you *really* want that dependency, change superclass and bam - affect all subclasses. Another obvious benefit of inheritance is of course "documentation structure" that you and other developers can understand. ...well. Of course, the above was written sloppily and can of course be refined or totally shot down. Feel free to do both! :) regards, Göran PS. Why oh why did Pharo lose the "double click on ? in the class browser to see inheritance textually"-mechanism? :)