Generics
Avi Bryant
avi at beta4.com
Sat Oct 4 20:37:41 UTC 2003
On Saturday, October 4, 2003, at 07:21 AM, Phil Hudson wrote:
> Thanks for replying, you've given me some food for thought and a
> possible
> solution - I hadn't thought of the #isBag approach. However, I think my
> problem is essentially insoluble in Smalltalk. I put this down to the
> lack of either multiple inheritance (yech) or interfaces (yay) in
> Smalltalk. In fact, I would go so far as to make this contentious
> claim:
> because of this lack, it is not possible to realize the Decorator
> design
> pattern cleanly, correctly and completely in Smalltalk. That is, you
> can
> never create a 100% transparently substitutable decorator object in
> Smalltalk. (I notice the illustrative code in the GOF is in C++). I
> hope
> I'm wrong about this, and that the real problem is just my boundless
> ignorance. Anybody?
The problem here is that in your eyes, "transparently substitutable"
necessarily includes the criteria "belongs to the same class". No
Smalltalker is going to accept that. What you have to realize is that
in Smalltalk, class is *purely* an implementation detail. It's a good
way of reusing method implementations, nothing more. In particular,
class *is not* the same thing as type. An object is not a collection
because it inherits from Collection, but because it implements #do: and
a few other methods. Inheriting from Collection is simply a (very)
convenient way of achieving this.
In the Ruby community, they call this "duck typing" - as in, "if it
walks like a...".
Actually, this isn't too different from Java - anything can implement
the Collection interface, and inheritance is just a convenient way of
doing this. The difference is that Java is statically typed, and so
needs the notion at compile time of a formal Interface. Smalltalk is
dynamically typed, and doesn't. I actually have exactly the same
problem with the use of instanceof in Java that I do with the use of
#isKindOf: in Smalltalk - you're breaking encapsulation in exactly the
same ways. It's just that in Java, there are fewer ways to work around
it (you can't add isCollection() to Object).
Phil, if you want to continue this discussion, we should maybe do it
privately - the list has had similar long threads before, and they can
get a little tiring.
>> It is cognate with instanceof, but that's a low level operation and
>> should
>> return a low level result.
>
> I'm unsure about the term "low level" in a Smalltalk context. Let's
> roll
> with it for now. Perhaps you could give some it some more definition
> in a
> follow-up.
A better term might have been "meta level". There are some attributes
of an object that are considered fairly private, and accessing these in
normal usage would break encapsulation. You will probably have no
problem accepting that instance variables fall into this category, for
example: most code should not be directly manipulating the values of an
object's inst vars. In Smalltalk, this is also true of an object's
class.
Now, there are in fact ways (#instVarAt:, #instVarNamed:) of accessing
inst vars, and even legitimate uses - an object database
implementation, for example, might well need to do this. Similarly,
there may well be special cases where you need to directly ask an
object what class it has using #isKindOf:, but it should be done with
the knowledge that you're breaking encapsulation to do so, and the
answer you get back should be an encapsulation-breaking answer.
To put this another way: I think you suggested writing an
implementation of #isKindOf: like this:
isKindOf: aClass
^ aClass == Bag or: [super isKindOf: aClass]
Say I had a class with an inst var 'foo' and a corresponding accessor
#foo. I decide to change the accessor name to #bar, In my mind, the
above implementation of #isKindOf: is equivalent to doing something
like this:
instVarNamed: aString
^ aString = 'bar'
ifTrue: [foo]
ifFalse: [super instVarNamed: aString]
It's the wrong place to put such abstractions.
More information about the Squeak-dev
mailing list
|