[squeak-dev] Re: [Pharo-project] Are Objects really hard?

Frank Shearar frank.shearar at gmail.com
Mon Feb 13 09:58:00 UTC 2012

2012/2/13 Göran Krampe <goran at krampe.se>:
> 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.

Well, we like to look at Java and hold our noses, but really, Java has
a rubbish type system, regardless of it being static. Now if you were
looking at some Haskell code, you'd see some highly polymorphic stuff
going on thanks to typeclasses. And in the dynamic functional language
corner you'd recognise good Smalltalk practice in Clojure's Protocols.
(They like to say that protocols solve the Expression Problem, but
really, it's multimethods that do that, not protocols.)

If you'd like to see Clojure's protocols in action, this is a nice
demonstration: http://news.ycombinator.com/item?id=3515862

The thing to bear in mind here is that (a) protocols won't surprise
you; they're "this thing responds to this set of messages" just as
you'd expect and (b) they do not pollute the global namespace: you can
add a method to some object _in a scoped manner_.

> 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.

But you realise the irony here, right? That if you google "parser
combinator" you hit all those "non-OO" languages like Haskell (and
then the new kids like Scala and F#). (Yes, yes, 3rd hit's Gilad's
talk. Not surprising.) But then, that in itself isn't terribly
surprising, because not many people get at a deep level that objects
are nothing more than higher order functions that close over

I have a long-running argument with a colleague who says (among other
reasons) that he thinks Smalltalk is rubbish because class-based
systems are rubbish (because of all the issues around inheritance).
But, of course, while we happen to use classes all the time, we don't
HAVE to. And, indeed, there are several prototype-based Smalltalk
libraries. Because, at its core, Smalltalk isn't about classes, it's
about objects sending messages to each other.

> 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.

Indeed: you should probably only use inheritance if you _have to_.
Exactly because it couples every class in an hierarchy together, and
you can no longer understand a method without understanding how that
method overrides/replaces/is overridden/is replaced in the tree.

> Another obvious benefit of inheritance is of course "documentation
> structure" that you and other developers can understand.

I'm sure we can do much better though. I'm thinking here of "this is a
Stream because it understands <set of standard Stream messages>".


> ...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? :)

More information about the Squeak-dev mailing list