scoops

advertisement
SCOOPS - the Scheme Object-Oriented Programming System
Documentation for the version for MIT Scheme 7.1
-----------------------------------------------Notes originally by Steve Sherin; revamped by Peter Ross, Dept of AI,
University of Edinburgh, 6 May 1991.
SCOOPS is copyright Texas Instruments; the following copyright notice
appears in the software:
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
;;;
Copyright (c) 1986 Texas Instruments Incorporated
Permission to copy this software, to redistribute it, and
to use it for any purpose is granted, subject to the
following restrictions and understandings.
1. Any copy made of this software must include this copyright
notice in full.
2. All materials developed as a consequence of the use of
this software shall duly acknowledge such use, in accordance
with the usual standards of acknowledging credit in academic
research.
3. TI has made no warranty or representation that the
operation of this software will be error-free, and TI is
under no obligation to provide any services, by way of
maintenance, update, or otherwise.
4. In conjunction with products arising from the use
of this material, there shall be no use of the name of
Texas Instruments (except for the above copyright credit)
nor of any adaptation thereof in any advertising, promotional,
or sales literature without prior written consent from TI in
each case.
Getting started
--------------You may have to find the file scoops.scm which contains the full
source. You can load it to get an interpreted version; there may be one
or both of scoops.bin and scoops.com in the same directory. To load,
just do
(load "<WHEREVER>/scoops")
and the loader will find the fastest-running version of the three
loadable forms.
If you can only find scoops.scm, you can compile it. First start up
Scheme with the compiler, by the UN*X command
% scheme -compiler
which typically takes a short while. Then, to compile scoops, execute
(cf "scoops.scm")
which will create both scoops.bin and scoops.com, but don't hold your
breath, go for a coffee instead. Afterwards, just load the system with
(load "scoops")
although you may prefer to restart Scheme without the compiler `band',
in order to save space, before loading SCOOPS.
Introduction
-----------SCOOPS is an object-oriented system written in Scheme. It offers
multiple rather than single inheritance, class variables as well as
instance variables, run-time addition and deletion of methods, active
values, and selectively settable/gettable/inittable instance variables.
There is no support for method combination, either by send-super or by
before/after daemons. If all this means nothing to you, it's time to go
and read up about object-oriented programming; this is not a primer.
The inheritance strategy used is pure depth-first, omitting any classes
already visited in the search; this is different from the `up-to-thejoins'
strategy used in some other object-oriented systems such as Flavors and
Loops.
Note that classes are defined in a global context.
The following section summarises the functions which comprise the user
level of the SCOOPS system.
Functions:
---------DEFINE-CLASS
(define-class <name>
(mixins <parent-classes>)
; optional
(classvars <binding-pairs or names for default value>) ; optional
(instvars
"
"
"
)
; optional
(options <set-spec> <get-spec> <init-spec>))
; optional
The CLASSVARS and INSTVARS can be just names, in which case those
variables will be given the default value of #f, or thye can be
specified as
(name initial-value)
pairs. The specification of INSTVARS can also include forms like
so:
(name (active init-value get-function set-function))
which indicates that the named variable is an active value. It will
have init-value as its initial value. The functions get-function
and
set-function should be functions of one argument. When the method
called GET-name is called, the get-function will be called with the
instance variable's current value as argument. When the method
called SET-name is called, the set-function will be called with the
new value as argument. The (active ...) specifications can be
nested arbitrarily deeply, using this form for the init-value. In
such a case all the set-functions are called in order, outermost
first, when the SET-name method is invoked. All the get-functions
are called whenever the GET-name method is invoked, but innermost
first.
Instance and class variables need not be accessed by SET-name
and GET-name methods. They can be treated as lexical variables for
the purposes of method definition, so that (say) a variable can
just
be set by doing a (SET! name ...). An active value is not triggered
by such lexical access; only the use of SET-name or GET-name
triggers it.
The <set-spec> can be
settable-variables
to cause automatic creation of methods named SET-name for all
class and instance variables. It can also be
(settable-variables <var1 .. varN>)
to cause SET-* methods to be created for only the named variables.
The <get-spec> is analogous to <set-spec>, causing creation of GET*
methods.
The <init-spec> can be
inittable-variables
so that keywords will be created for all instance variables for use
in a call of MAKE-INSTANCE (see below). It can also be
(inittable-variables <var1 ... varN>)
to make only some be initialisable in this way.
Example:
(define-class warship
(mixins ship military-equipment)
(classvars
(no-of-warships 0))
(instvars
guns
shells)
(options
(settable-variables shells) ; cannot change guns!
gettable-variable
; but can ask about anything
inittable-variables))
; and specify when creating.
MAKE-INSTANCE
(make-instance name '<var1> <val1> ... '<varN> <valN>)
returns an instance of class name with those variables bound
to those values provided they are declared inittable when the class
was defined.
Use a variable to bind the instance returned as it does not sideeffect
the environment. Example:
(define victorious
(make-instance warship
'guns
6
; can init this, but no set-guns method.
'shells 500
; can init this, & there is a set-shells.
'country "tibet") ; variable presumably inherited from
ship?
COMPILE-CLASS
(compile-class <class>)
sets up the environments for classvars and methods. This is done
automatically anyway when the first class instance is created, but
you may prefer to cause the slight delay to happen at a time of
your
choosing. The information provided by DESCRIBE-CLASS will be
incomplete until the class is `compiled'.
Note that the `compilation' of a class does not force the
compilation of its mixins, nor is it necessary for the mixins to
be compiled before a class (or at all). The compilation merely
searches
the inheritance graph for the class variables and methods and
creates Scheme environments in which these exist together; these
environments are used in instance creation, which is why the
compilation happens automatically upon creation of the first
instance. This `compilation' means that when a message is sent to
an instance, the inheritance graph does not have to be re-searched
each time.
However, if a class has been compiled already and then a method is
added to or deleted from the class or any mixin, then there is no
need to recompile the class or any other class of which it is a
mixin. SCOOPS handles this automatically.
CLASS-OF-OBJECT
(class-of-object <obj>)
simply returns the class-name of the class of an object.
NAME->CLASS
(name->class '<name>)
returns the class named by <name>.
METHODS
(methods <class>)
returns a list of names of methods available to that class and
defined
within that class.
ALL-METHODS
(all-methods <class>)
returns a list of names of methods available to the class,
including
inherited methods.
CLASSVARS
(classvars <class>)
returns a list of the names of classvars of the class itself.
ALL-CLASSVARS
(all-classvars <class>)
returns a list of the names of classvars of the class and all those
it
inherits from.
INSTVARS
(instvars <class>)
returns a list of the names of the instance variables of the class,
but not any inherited ones.
ALL-INSTVARS
(all-instvars <class>)
returns a list of the names of instance variables, including
inherited ones.
MIXINS
(mixins <class>)
returns names of all of the class's parents.
RENAME-CLASS
(rename-class (<old> <new>))
redefines <old> as <new>, replacing the internal name flags.
GETCV
(getcv <class> <class-var>)
returns a gettable class-var.
SETCV
(setcv <class> <class-var> <val>)
sets a settable class-var to val.
CLASS-COMPILED?
(class-compiled? <class>)
returns #t if the class has been `compiled' already, either by
COMPILE-CLASS or automatically upon instance creation.
DESCRIBE
(describe <instance-or-class>)
prints relevant information about either a class or an instance. If
the class has not yet been `compiled' the information will be
incomplete.
The information will, however, tell you whether the class has been
compiled.
SEND
(send <instance> <message> <optional-arguments>)
evaluates <message> with respect to the class and instance and
whatever
arguments are required. SEND causes an error if the class has no
method for the message. You may prefer to use SEND-IF-HANDLES
instead.
SEND-IF-HANDLES
(send-if-handles <instance> <message> <optional-arguments>)
Send-if-handles returns #f if the method (message) is inappropiate,
otherwise behaves like SEND.
DEFINE-METHOD
(define-method (<class> <method-name>)
<lambda-list>
<body>)
defines a function that has access to class and instance variables
for the class, including inherited ones. All such variables can be
regarded as lexical variables in scope for the body of the method;
the variables are also accessible by SET-name and GET-name methods
if these exist. Any methods accessible to the class can be called
as procedures within the body, so there is no need for a pseudovariable called SELF such as is provided by many other objectoriented systems.
DELETE-METHOD
(delete-method (<class> <method-name>))
destroys the named method of the given class.
Download