[comp.lang.eiffel] Smalltalk types

wilson@carcoar.Stanford.EDU (Paul Wilson) (09/09/89)

[This is a slightly revised version of something I posted, but
which looks from here like it never got out to the net.  Sorry
for any redundancy.  -- PRW]

It seems to me that types are abstracted *roles* that objects can play.
The same set of messages may mean a different thing in one role
than in another, so sets of messages really don't capture this
intuition.

For example in my role as a computer scientist, if somebody asks
me "what do you do?" I respond in one way, but in my role as
a boardsailer, I respond in another.  So at a conference, I
may say "garbage collection and reconstructive memory," but
at the beach I say "I fall down a lot."

Similarly, when an object is of more than one type, you get
collisions between messages understood by one type and same-named
messages understood by another.  For example, suppose a window
object responds to a "size" message by returning a point object
giving its screen dimensions in pixels;  suppose also that
a queue object responds by returning an integer saying how
many things are in the queue.

What happens when an object is both a queue and a window (say,
because it's a queue that can represent its contents to the
user)?

It seems to me that the "right," intuitive way to do this,
in a strongly typed system, is to resolve this by the
role the object is playing.  If the window system has
a pointer to it *as a window*, it should respond as
a window.  And if a simulation object has a pointer to
it *as a queue*, it should respond as a queue.

Does anybody do types this way?  It seems to me the most
natural way to do things:  if an object is of multiple
types, it has multiple interfaces -- different "languages"
it can speak.  And different languages may have the same
words, but with different meanings.  That's okay, as
long as the object knows what language it's being
spoken to in.

This leads to a more refined notion of type safety -- not
only should an object "understand" all messages that could
be sent to it at runtime (in the sense of having a method
defined for that message), but it should understand it
_in_the_right_way_.  It should be speaking the "same language"
as the message sender.

In summary:

A type should be a role with an associated protocol.
That's different from a set of messages, since two
different protocols could use exactly the same message
selectors and mean entirely different things.  So it's more
abstract that syntactically matching messages to method names.

It's also different from a class, because it's *not* a statement
about implementation.  Different objects of (subtypes of) the
same type do "the same thing" in response to the same messages,
even if they do it "in different ways," as determined by their
implementations.

And a class is a particular implementation that implements one
or more types.  Note that all of these things have identities
rather than just properties;  even types should be testable
for identity as well as the strucural equivalence
implied by accepting a particular set of messages.

On this view, types end up being capabilities to which
access can be restricted via scoping or maybe (if they're
first class) by controlling who they're handed to.
One object might be allowed to see another object
as "an underling I can order around," while yet another is
only allowed to see it as "a peer I can't talk to that way."

Now it's not clear to me that making all these distinctions,
but it seems like the kind of explicitness static-typing fans
would like.

Any comments?  Whose wheels am I reinventing? :-)

      -- Paul


Paul R. Wilson                         
Software Systems Laboratory               lab ph.: (312) 996-9216
U. of Illin. at C. EECS Dept. (M/C 154)   wilson@bert.eecs.edu
Box 4348   Chicago,IL 60680 


Paul R. Wilson                         
Software Systems Laboratory               lab ph.: (312) 996-9216
U. of Illin. at C. EECS Dept. (M/C 154)   wilson@carcoar.stanford.edu
Box 4348   Chicago,IL 60680