[comp.lang.scheme] Object oriented programming in Scheme

adams@tekchips.tek.COM (Norman Adams) (12/22/87)

    ... I'd like
    to hear from anybody who has tried to implement major T facilities (namely:
    object/operation facility) in MacScheme.

    Lars Ericson
    ericson@csd16.nyu.edu

We have been experimenting with an object system based on T's.  We have a
prototype implementation which we are evaluating, and we hope to have
something interesting to say in a few months.  If all goes well, there is
some chance we will make source available for a sample implementation.  

For those not familiar with the T object system:  I eschew zealotry, but I
find the T approach (roughly closures + dispatch) more in the Scheme spirit
than anything in the Flavors family.  Our changes to the T object system
are intended to make reasonably fast implementions possible.  I would
consider an implementation reasonably fast if time to send a message, do
the method lookup, and pass control to the method, is less than the cost of
2 procedure calls in the worst case.

Our prototype is almost portable Scheme.  We also have a faster version
that is quite specific to MacScheme.  In a single, simple-minded benchmark,
compared to Ulrich's SCOOPS for MacScheme:  the slow version is 20% the
speed, the faster version 2 or 3 times the speed (that's 5 procedure call
times).  I would guess that, a few lines of assembly code, in a few key
places, are needed to make the MacScheme version "reasonably fast."  

Norman Adams
Computer Research Lab
Tektronix Labs
-------

jeff@aiva.edinburgh.ac.UK (Jeff Dalton) (12/22/87)

> Date: Mon, 21 Dec 87 12:15:32 PST
> From: Norman Adams <adams%com.tek.tekchips@net.cs.relay>

> We have been experimenting with an object system based on T's.  [...]

> For those not familiar with the T object system:  I eschew zealotry, but I
> find the T approach (roughly closures + dispatch) more in the Scheme spirit
> than anything in the Flavors family.  Our changes to the T object system
> are intended to make reasonably fast implementions possible.  I would
> consider an implementation reasonably fast if time to send a message, do
> the method lookup, and pass control to the method, is less than the cost of
> 2 procedure calls in the worst case.

This is interesting.  If you don't mind saying something about your
implementation short of posting the source, I'd like to hear more.

It seems that you'll always have to do two procedure calls: one for
the operation and another for the method; three if you must also call a
handler that returns the method.  And that still leaves the method lookup
itself.  Flavors are about the same: one for the generic function, one
for the method, and about a call's worth (let's say) for looking up the
method.  So, generic operations should have 2-3 times the overhead of an
equivalent function.  But...

I recently implemented a T-like system in a completely straightforward
way in Common Lisp.  I expected an operation to take 3 calls (operation,
handler, method), and timing with KCL on a VAX more or less confirmed
this.  Here procedure calls were pretty expensive because they used
CALLS.  I reasoned that they might be less dominant on a Sun, so I tried
again on a 3/260.  To make this even less meaningful, I used Sun Common
Lisp this time.  Calling a (generic) operation on an object with just one
method that returned the square of its arguement (this is what I was
doing) took 1.9 times longer then an equivalent function when both were
adjusted to take out the time required to square in-line.  The total
time (10000 iterations) was still pretty small, though, so the results
may not be very meaningful.  Why was the factor 1.9 instead of, say, 3?
I don't know.

In any case, it's difficult to implement T objects exactly.  T objects
can be used as functions, and it's difficult to get most Lisp systems to
accept new kinds of function objects.  So, since I couldn't do

     (OBJECT fn . clauses)

I just implemented

     (OBJECT . clauses)

I also had operation lookup based on the name of the operation.  That
is, the dispatch function had (cond ((eq request 'op)) ...) instead of
(cond ((eq request op)) ...).

There's a certain elegance to this system that I didn't fully appreciate
until I'd used it for a while.  Now I even miss the objects-as-functions.
Nonetheless, it is somewhat inflexible.  You can't add new methods
incrementally (they must all be there in the OBJECT body), for example.

Jeff Dalton,                      JANET: J.Dalton@uk.ac.ed             
AI Applications Institute,        ARPA:  J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!J.Dalton