Newsgroups: comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!pipex!uunet!zib-berlin.de!cs.tu-berlin.de!informatik.uni-bremen.de!marvin.pc-labor.uni-bremen.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!stepsun.uni-kl.de!uklirb.informatik.uni-kl.de!superieur!leidig
From: leidig@informatik.uni-kl.de (Torsten Leidig)
Subject: Re: Choice of OOP for Scheme
Message-ID: <1995Jan31.112119.8057@uklirb.informatik.uni-kl.de>
Sender: leidig@informatik (Torsten Leidig)
Nntp-Posting-Host: classico.informatik.uni-kl.de
Reply-To: leidig@informatik.uni-kl.de (Torsten Leidig)
Organization: University of Kaiserslautern
References: <philo-2301951744090001@mac-h164e.cogsci.ed.ac.uk>    <DMEGGINS.95Jan23152149@aix1.uottawa.ca>    <D2xGFv.19E@cc.umontreal.ca>    <3g5vau$3b1@agate.berkeley.edu> <philo-2601951847490001@mac-h164e.cogsci.ed.ac.uk> <thinmanD332tF.7x2@netcom.com>
Date: Tue, 31 Jan 1995 11:21:19 GMT
Lines: 97


--

In my interpreter I have implemented an o-o style that is in between
the class-based style of CLOS and the prototype-based one of Self. Essentially
the idea is to be prototype-based but provide an abstraction layer for the
class-based style.

Therefore I extended my Scheme with a new data type "object", generic functions
and very few special forms.

Objects
=======
For an object it is best you think of a vector of values. Although it is not
generally nesseccary, all objects are derived from the root "object", which
consists of two values: A "parent" value (initially #f) an a "template" value.
The "parent" value is responsible for method delegation and the 
"template" value gives names for each slot of the object (e.g. something like
'(parent template) for the root object).

A new prototype is created from an existing one:

(define foo (prototype bar '(hack . 3)))    -- procedure
            ---------------------------

This means a new object with a shallow copy of object "bar" and
one more slot "hack" is created. The parent value of foo is set to "bar"
and the template is updated to hold the name of slot "hack".

Multiple inheritance is possible, however I consider it a topic which should
kept out of a possible o-o extension of scheme.

An object can be cloned via the generic function "make":

foo => an object

(make foo 'hack 4)  => an object      -- procedure
------------------

This is a shallow copy of object "foo". Slots can be overriden using an optional
argument list.

Access to slots
===============

Slots can be accessed outside of a generic function. This is for rapid
prototyping. Therefore a new special form is introduced:

(foo hack) => 3   for getting the value of slot named "hack"
----------
Note: This can hardly be implemented in Scheme because foo is not a function
or a macro. The other way round, writing "(hack foo)" requires hack to be
a macro.

(set foo 'hack 4)  => 4   for setting the value of slot named "hack"
-----------------

Maybe a new special form for setting makes more sense, f.i. (set! (foo hack) 4).

Beside of the generic "set" procedure there are no extra setter or
getter procedures. (for sake of simplicity)

Inside generic functions (see below) slot names are in the lexical scope, so
no special forms or procedures are needed!

Generic functions
=================

Scheme was extended with a kind of generic function, with dispatching 
using the first argument. Dispatching is done only for objects. If the
first argument isn't an object then the default procedure is invoked, which
can be defined by an ordinary Scheme "define".

Generic functions are defined via a special form:

(define-method ((<fnname> foo) this <fnarguments>) <body>) -- syntax
----------------------------------------------------------

A more generalized view of generic functions, which also draws basic Scheme
types and dispatching with multiple arguments into account is topic of future
developments.

We are using this small o-o extension of scheme in various projects including
a graphical audio/video editor. The whole set of graphical user interface
objects (Xm or Win32 based) and multimedia objects are modelled this way.

So our "Hello World!" looks as follows:

(require 'PushButton)

(realize (make PushButton
                 'labelString "Hello World!"
                 'activateCallback exit))



Torsten Leidig
