visibility" of class object in favour of a global context

Avi Bryant avi at beta4.com
Wed May 28 06:06:30 UTC 2003


On Tue, 27 May 2003, Joel Shellman wrote:

> > On Tue, 27 May 2003, Joel Shellman wrote:
> > Yes, in Java you would.  But if you were designing your Java code to be as
> > flexible as possible, you wouldn't be testing for a class, would you?
> > You'd probably be testing for an interface.
>
> It's done the same way--instanceof.

Yes, I know.

> > That way, anyone that
> > implements the right methods will get treated the same, no matter where in
> > the inheritance hierarchy they happen to be.
>
> Which is what I said in the following paragraph.

No; my point was *anywhere* in the inheritance hierarchy, including being
completely unrelated to the class you're testing for (ie, Foo).  But this
is a side issue...

> > Smalltalk doesn't have explicit interfaces (perhaps you could argue that
> > it should), but #isFoo methods amount to more or less the same thing - if
> > an object wants to claim to be a Foo by implementing #isFoo to return
> > true, you should take it at its word, not be impolite and look at anything
> > so private as its class.  This allows, for example, Todd Blanchard to
> > implement a parallel ProtoMorph hierarchy that doesn't inherit any code
> > from Morphic, but still interoperates with it.
>
> Given that information, it seems to me even more strange to put #isFoo on
> Object.

Why?

> > In general, it is considered bad form in Smalltalk to do *anything* based
> > on the class of an object, unless you're the method dispatch part of the
> > VM.
>
> Ah, that's good to know.

But I don't think you've thought through the full implications of it.  You
seem to be suggesting that, for example, rather than the Compiler sending
#isLiteral, there ought to be some Compiler>>isLiteral: anObject method
somewhere.  But what would this look like?  Presumably a bunch of tests to
see what class it is...

We have a mechanism for doing different things based on class, it's called
message dispatch.  It's more efficient and more flexible than any switch
statement you might roll yourself.

> I could understand this in a prototype-based system, but it still doesn't
> make sense to me for in a class based system. Actually, I was considering
> enhancing the Array type the other day in javascript (didn't seem like it
> was going to work, though--IE 5.5 doesn't support that kind of thing I
> think).

Interesting.  I can think of no reason why this would seem more natural in
a prototype system than in a class system, except if the only class
systems you were familiar with were Java and C++...

> But why? Why do you need to "pollute the holy shrine" when those methods
> could just as easily be somewhere within your own category? Generally, (I
> think) any method you can put on one side of interoperability between two
> classes, could be put on the other side instead (or with some class in
> between).

But that's the thing.  This simply isn't true.
Let me give you an example from the image.  One of the many, many methods
on Object is #inspect.  I'm sure you've used it, at least implicitly, by
now.  And I have no doubt that you would feel it cleaner/better to have
"Inspector inspect: someObject" rather than "someObject inspect".  Right?

But you need different inspectors depending on what kind of an object it
is.  The inspector that comes up on an OrderedCollection doesn't actually
show you the instance variables, it shows you the objects contained in
that collection.  Ditto for a Dictionary, which shows the key/value pairs
(and has some extra menu items to add and remove keys).  How should this
work?

Well, again, you could say that Inspector should know how to pick the
right one.  This is the general argument you're making, I think.  So
somewhere you have code like

(object isKindOf: Dictionary)
  ifTrue: [self openDictionaryInspectorOn: object]
  ifFalse:
    [(object isKindOf: Collection)
       ifTrue: [self openCollectionInspectorOn: object]
       ifFalse: [self openNormalInspectorOn: object]]

Never mind that this reimplements method lookup in the ugliest way (note
that I had to put the test for Dictionary before the test for Collection,
because Dictionary is a subclass of Collection).  What happens if I write
a new class, specific to my package, that I want to implement a custom
inspector for?  It seems like the only thing I can do is go in and hack
that method in Inspector to add another clause with another #isKindOf:...
and *that* is breaking modularity.

Luckily, all I have to do is implement #inspect on my class.  And now
every tool in the system - debuggers, explorers, workspaces - brings up my
special, custom inspector, without having a clue that my special class
even exists.

If I can take this one step further - we already have #inspect in the
image, to bring up Morphic and MVC inspectors, and this is already
overridden by Collection, Dictionary, etc.  But this isn't useful for
another UI - like, say, my Seaside web framework, which has web based
inspectors of its own.  What cleaner way could I possibly use to choose
how to display a particular object on the web, than by adding appropiate
new methods to Object, Collection, Dictionary...?

Avi



More information about the Squeak-dev mailing list