@setchapternewpage odd
@synindex vr fn
-@c $Id: sos.texinfo,v 1.6 1994/06/01 20:15:23 cph Exp $
+@c $Id: sos.texinfo,v 2.1 1997/06/25 07:22:56 cph Exp $
@set TITLE The SOS Reference Manual
-@set EDITION 1.6
-@set UPDATED 1 June 1994
-@set UPDATE-MONTH June 1994
+@set EDITION 2.0
+@set UPDATED 25 June 1997
+@set UPDATE-MONTH June 1997
@ifinfo
-Copyright @copyright{} 1993-94 Massachusetts Institute of Technology
+Copyright @copyright{} 1993-97 Massachusetts Institute of Technology
This is Edition @value{EDITION}, last updated @value{UPDATED}, of
@cite{@value{TITLE}}.
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1993-94 Massachusetts Institute of Technology
+Copyright @copyright{} 1993-97 Massachusetts Institute of Technology
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and Computer
@end enumerate
@end titlepage
+@ifinfo
@node Top, Object System, (dir), (dir)
This is Edition @value{EDITION}, last updated @value{UPDATED}, of
* Object System::
* Variable Index::
* Concept Index::
-
- --- The Detailed Node Listing ---
-
-The Object System
-
-* Language::
-* Reflective Operations::
-* Meta-Object Protocol::
-* Miscellany::
-
-The Language
-
-* Classes::
-* Predefined Classes::
-* Instances::
-* Slots::
-* Generic Procedures::
-* Methods::
-* Record Classes::
-
-Reflective Operations
-
-* Class Reflectives:: Reflective Operations on Classes
-* Generic Reflectives:: Reflective Operations on Generic Procedures
-* Method Reflectives:: Reflective Operations on Methods
-* Slot Reflectives:: Reflective Operations on Slots
-
-The Meta-Object Protocol
-
-* Generic Invocation Subprotocol::
-* Instantiation Subprotocol::
-* Class Initialization Subprotocol::
@end menu
+@end ifinfo
@node Object System, Variable Index, Top, Top
-@chapter The Object System
+@chapter An Object System
@sc{sos} is a Scheme @dfn{object system} derived from Tiny @sc{clos}
@footnote{Tiny @sc{clos} was written by Gregor Kiczales of Xerox
@sc{parc}; @sc{sos} is derived from version 1.2 of Tiny @sc{clos}.},
which in turn was loosely derived from @sc{clos}, the Common Lisp Object
System. Its basic design and philosophy is closely related to Tiny
-@sc{clos}, but there are differences in naming, interface, and in the
-meta-object protocol.
+@sc{clos}, but there are differences in naming and interface.
+
+This document is a reference manual, and as such does not attempt to
+teach the reader about object-oriented programming. It is assumed that
+you already have a passing familiarity with @sc{clos} and with Scheme.
In the procedure descriptions that follow, certain argument names imply
-restrictions on the corresponding argument:
+restrictions on the corresponding argument. Here is a table of those
+names. The parenthesised name in each entry is the name of the
+predicate procedure that the argument must satisfy.
@table @var
@item class
-The argument must be a @dfn{class}, i.e.@: it must satisfy the predicate
-@code{class?}.
+The argument must be a @dfn{class} (@code{class?}).
@item instance
-The argument must be an @dfn{instance}, i.e.@: it must satisfy the
-predicate @code{instance?}.
+The argument must be an @dfn{instance} (@code{instance?}).
@item name
-The argument must be a symbol.
+The argument must be a symbol (@code{symbol?}); sometimes this is also
+allowed to be @code{#f} (@code{false?}).
@item generic-procedure
-The argument must be a @dfn{generic procedure}, i.e.@: it must satisfy
-the predicate @code{generic-procedure?}.
-
-@item generic
-The argument must be a @dfn{generic procedure instance}, i.e.@: it must
-satisfy the predicate @code{(lambda (x) (instance-of? x <generic>))}.
+The argument must be a @dfn{generic procedure}
+(@code{generic-procedure?}).
@item method
-The argument must be a @dfn{method}, i.e.@: it must satisfy the
-predicate @code{(lambda (x) (instance-of? x <method>))}.
+The argument must be a @dfn{method} (@code{method?}).
+
+@item specializer
+The argument must be a @dfn{method specializer} (@code{specializer?}).
@item procedure
-The argument must be a procedure.
+The argument must be a procedure (@code{procedure?}).
@item slot
-The argument must be a @dfn{slot descriptor}, i.e.@: it must satisfy the
-predicate @code{slot?}.
-
-@item plist
-The argument must be a @dfn{property list}, i.e.@: it must be a list of
-even length, the even-numbered elements of which must be symbols.
+The argument must be a @dfn{slot descriptor} (@code{slot-descriptor?}).
@end table
-@menu
-* Language::
-* Reflective Operations::
-* Meta-Object Protocol::
-* Miscellany::
-@end menu
-
-@node Language, Reflective Operations, , Object System
-@section The Language
-
@menu
* Classes::
-* Predefined Classes::
* Instances::
* Slots::
* Generic Procedures::
* Methods::
-* Record Classes::
+* Printing::
@end menu
-@node Classes, Predefined Classes, , Language
-@subsection Classes
+@node Classes, Instances, Object System, Object System
+@section Classes
@cindex class
@cindex instance
A @dfn{class} is an object that determines the structure and behavior of
-a set of other objects, which are called its @dfn{instances}.
+a set of other objects, which are called its @dfn{instances}. However,
+in this document, the word @dfn{instance} usually means an instance of
+the class @code{<instance>}.
@cindex subclass
@cindex superclass
@cindex local precedence order
@cindex precedence order, local
@cindex order, local precedence
-When a class is defined, the order in which its direct superclasse are
+When a class is defined, the order in which its direct superclasses are
mentioned in the defining form is important. Each class has a
@dfn{local precedence order}, which is a list consisting of the class
followed by its direct superclasses in the order mentioned in the
Classes are organized into a @dfn{directed acyclic graph}. There are
two distinguished classes, named @code{<object>} and @code{<instance>}.
The class named @code{<object>} has no superclasses. It is a superclass
-of every class except itself. The class named @code{<instance>} is an
-instance of the class @code{<class>} and is a superclass of every class
-that is an instance of @code{<class>} except itself.
-
-@cindex metaclass
-Classes are represented by objects that are themselves instances of
-classes. The class of the class of an object is termed the
-@dfn{metaclass} of that object. When no misinterpretation is possible,
-the term @dfn{metaclass} will be used to refer to a class that has
-instances that are themselves classes. The metaclass determines the
-form of the instances of those classes. @sc{sos} provides a default
-metaclass, @code{<class>}, that is appropriate for most programs. The
-meta-object protocol provides mechanisms for defining and using new
-metaclasses.
-
-Except where otherwise specified, all classes mentioned in this chapter
-are instances of the class @code{<class>}, all generic procedures are
-instances of the class @code{<generic-procedure>}, and all methods are
-instances of the class @code{<method>}.
-
-@deffn Syntax define-class name direct-superclasses direct-slot @dots{}
-Define @var{name} to be a class. In its basic form, @code{define-class}
-might have been defined by
+of every class except itself. The class named @code{<instance>} is a
+direct subclass of @code{<object>} and is the base class for
+@dfn{instance} objects. Instances are special because @sc{sos} has
+efficient mechanisms for dispatching on them and for accessing their
+slots.
-@lisp
-(define-syntax define-class
- (syntax-rules ()
- ((define-class name (class ...) slot ...)
- (define name
- (make-class (quote name)
- (list class ...)
- (quote (slot ...)))))))
-@end lisp
-
-Note that slot options are handled specially by @code{define-class}. If
-a @var{direct-slot} specifies a slot options property list, the keys of
-the property list (i.e.@: the even-numbered elements) are not evaluated,
-while the datums of the property list @emph{are} evaluated. The
-expansion above does not show the proper treatment of slot options.
+@menu
+* Class Datatype::
+* Predefined Classes::
+* Record Classes::
+* Specializers::
+@end menu
-@cindex class options
-@code{define-class} permits the specification of @dfn{class options},
-which are options that pertain to the class as a whole. Class options
-are specified by overloading @var{name}: instead of a symbol, specify a
-pair whose @sc{car} is a symbol and whose @sc{cdr} is an alist. At
-present only one class option is recognized:
+@node Class Datatype, Predefined Classes, Classes, Classes
+@subsection Class Datatype
-@table @code
-@item (metaclass @var{class})
-Specifies that @var{class} is the metaclass of the class being defined.
-If this option is not given, the metaclass defaults to @code{<class>}.
-@end table
-@end deffn
+The procedures in this section may be used to construct and inspect
+classes.
@deffn Procedure make-class name direct-superclasses direct-slots
Creates and returns a new class object.
Each of the elements of @var{direct-slots} defines one slot named
@var{name}. @var{Plist} is used to describe additional properties of
-that slot. The meaning of @var{plist} is defined by
-@code{compute-slot-descriptor}; by default these properties are
-recognized:
+that slot. The following properties are recognized:
@table @code
-@item initializer
-A procedure of no arguments that is called (by @code{allocate-instance})
-whenever an instance containing this slot is created. The value
-returned by the procedure is the initial value of the slot. If the
-@code{initializer} property is not specified, or if it is specified as
-@code{#f}, the slot is not initialized.
+@item initial-value
+This property specifies the default initial value for the slot, i.e.@:
+the value stored in the slot when an instance is created and no value is
+explicitly specified by the instance constructor. If neither the
+@code{initial-value} nor the @code{initializer} property is specified,
+the slot has no default initial value.
-The use of the @code{initializer} is automatic if the slot has an
-@code{allocation} of @code{instance}; otherwise the meta-object protocol
-must invoke @code{initializer} and use its value to initialize the slot.
+@item initializer
+This property specifies a procedure of no arguments that is called by an
+instance constructor whenever an instance containing this slot is
+created. The value returned by the @code{initializer} procedure is the
+initial value of the slot.
@item accessor
This property specifies a generic procedure; @code{make-class} will add
This property specifies a generic procedure; @code{make-class} will add
an ``initialized?''@: predicate method for this slot to the procedure.
@xref{Slots}.
+@end table
+
+Slot properties are combined in slightly complicated ways.
+
+@itemize @bullet
+@item
+It is not allowed to specify both @code{initial-value} and
+@code{initializer} for a slot in a given call to @code{make-class}; at
+most one of these properties may be given.
+
+@item
+If a slot is specified for a given class, and a slot of the same name is
+inherited from a superclass, then the slot properties for the two slots
+are combined. Slot properties from the subclass shadow those of the
+superclass. However, if a superclass has a slot property, and the
+subclass does not, the property is inherited. The resulting class never
+has more than one slot of a given name.
+
+@item
+When combining superclass and subclass slots, @code{initial-value} and
+@code{initializer} shadow one another. In other words, regardless of
+the inherited slot properties, the resulting slot has at most one of
+these two properties.
+@end itemize
+
+Examples of @code{make-class}:
-@item allocation
-A symbol describing how the slot should be allocated. If the
-@code{allocation} property is the symbol @code{instance}, or if it is
-not specified, then the slot is an ordinary instance slot. Otherwise
-the slot is a virtual slot and the meaning of the symbol is defined by
-the virtual slot protocol.
+@lisp
+@group
+(define <cell>
+ (make-class '<cell> '() '()))
+@end group
+
+@group
+(define <contact>
+ (make-class '<contact>
+ (list <cell>)
+ `((name accessor ,cell-name))))
+@end group
+
+@group
+(define <compound-cell>
+ (make-class '<compound-cell>
+ (list <cell>)
+ `((width accessor ,cell-width)
+ (height accessor ,cell-height)
+ (components accessor ,cell-components
+ modifier ,set-cell-components!
+ initial-value ()))))
+@end group
+@end lisp
+@end deffn
+
+@deffn Syntax define-class name direct-superclasses direct-slot @dots{}
+Define @var{name} to be a class. In its basic form, @code{define-class}
+might have been defined by
+
+@lisp
+@group
+(define-syntax define-class
+ (syntax-rules ()
+ ((define-class name (class ...) slot ...)
+ (define name
+ (make-class (quote name)
+ (list class ...)
+ (quote (slot ...)))))))
+@end group
+@end lisp
+
+Note that slot properties are handled specially by @code{define-class}.
+If a @var{direct-slot} specifies a slot properties property list, the
+keys of the property list (i.e.@: the even-numbered elements) are not
+evaluated, while the datums of the property list @emph{are} evaluated.
+The expansion above does not show the proper treatment of slot
+properties.
+
+In addition to the slot properties recognized by @code{make-class},
+@code{define-class} recognizes a special slot property, called
+@code{define}. The @code{define} property specifies that some or all of
+the slot accessors should be defined here; that is, generic procedures
+should be constructed and bound to variables, and then the accessor
+methods added to them.
+
+The argument to the @code{define} property is a list containing any
+combination of the symbols @code{accessor}, @code{modifier}, and
+@code{initpred}. As an abbreviation, the argument may be one of these
+symbols by itself, which is equivalent to the list containing that
+symbol. Also, the argument may be the symbol @code{standard}, which is
+equivalent to @code{(accessor modifier)}.
+
+The argument to @code{define} specifies which accessors will be defined
+by this form. The accessors are defined using default names, unless the
+names are overridden by the corresponding slot property. The default
+names for a class @code{<foo>} and a slot @code{bar} are @code{foo-bar},
+@code{set-foo-bar!}, and @code{foo-bar-initialized?}, respectively for
+the accessor, modifier, and initpred. For example,
+
+@lisp
+@group
+(define-class foo
+ (bar define accessor))
+@end group
+@end lisp
+
+@noindent
+defines an accessor called @code{foo-bar}, but
+
+@lisp
+@group
+(define-class foo
+ (bar define accessor accessor foo/bar))
+@end group
+@end lisp
+
+@noindent
+instead defines an accessor called @code{foo/bar}. Finally,
+
+@lisp
+@group
+(define-class foo
+ (bar accessor foo/bar))
+@end group
+@end lisp
+
+@noindent
+doesn't define any accessor, but assumes that @code{foo/bar} is a
+previously-defined generic procedure and adds an accessor method to it.
+
+@cindex class options
+@code{define-class} permits the specification of @dfn{class options},
+which are options that pertain to the class as a whole. Class options
+are specified by overloading @var{name}: instead of a symbol, specify a
+pair whose @sc{car} is a symbol and whose @sc{cdr} is an alist. The
+following class options are recognized:
+
+@table @code
+@item (predicate @var{[name]})
+Specifies that a predicate procedure should be defined for this class.
+@var{Name} must be either a symbol or @code{#f}: a symbol specifies the
+name that will be bound to the predicate procedure, and @code{#f}
+specifies that no predicate procedure should be defined. If @var{name}
+is omitted, or if no @code{predicate} option is specified, a predicate
+procedure is defined by appending @code{?} to the name of the class. If
+the class name is surrounded by angle brackets, they are stripped off
+first. For example, the default predicate name for the class
+@code{<foo>} is @code{foo?}.
+
+@item (constructor @var{[name]} @var{slot-names} @var{[n-init-args]})
+Specifies that a constructor procedure should be defined for this class.
+@var{Name} must be a symbol, which is the name that will be bound to the
+predicate procedure; if omitted, a default name is formed by prepending
+@code{make-} to the name of the class. If the class name is surrounded
+by angle brackets, they are stripped off first. For example, the
+default constructor name for the class @code{<foo>} is @code{make-foo}.
+
+@var{Slot-names} and @var{n-init-args} correspond to the arguments of
+the respective names accepted by @code{instance-constructor}, and can
+take any of the allowed forms for those arguments.
@end table
-Please note that the following are equivalent, although the former is
-slightly faster:
+Examples of @code{define-class} (compare these to the similar examples
+for @code{make-class}):
+
+@lisp
+(define-class <cell> ())
+
+@group
+(define-class (<contact> (constructor (name) no-init)) (<cell>)
+ (name accessor cell-name))
+@end group
+
+@group
+(define-class (<compound-cell> (constructor ())) (<cell>)
+ (width accessor cell-width)
+ (height accessor cell-height)
+ (components accessor cell-components
+ modifier set-cell-components!
+ initial-value '()))
+@end group
+@end lisp
+@end deffn
+
+@deffn Procedure make-trivial-subclass superclass1 superclass2 @dots{}
+This convenience procedure makes a subclass that defines no new slots,
+and that inherits from the given superclasses. It is equivalent to the
+following
@lisp
-(make-class @var{name} @var{superclasses} @var{slots})
-(make-instance <class> @var{name} @var{superclasses} @var{slots})
+@group
+(make-class (class-name @var{superclass1})
+ (list @var{superclass1} @var{superclass2} @dots{})
+ '())
+@end group
@end lisp
@end deffn
@code{#f}.
@end deffn
+@deffn Procedure subclass? class specializer
+Returns @code{#t} if @var{class} is a subclass of @var{specializer},
+otherwise returns @code{#f}. If @var{specializer} is a class, the
+result follows from the above definition of subclass, except that a
+class is a subclass of itself. If @var{specializer} is a record type,
+it is equivalent to having used the @code{record-type-class} of the
+record type. Finally, if @var{specializer} is a union specializer,
+@code{subclass?} is true if @var{class} is a subclass of one or more of
+the component classes of @var{specializer}.
+@end deffn
+
@deffn Procedure object-class object
Returns the class of @var{object}. @var{Object} may be any Scheme
-object; if @var{object} is known to be an instance, it is better to use
-@code{instance-class} rather than @code{object-class}.
+object; if @var{object} is known to be an instance,
+@code{instance-class} is faster than @code{object-class}.
@end deffn
-@deffn Procedure instance-class instance
-Returns the class of @var{instance}.
+@deffn Procedure class-name class
+Returns the name of @var{class}. This is the @var{name} argument passed
+to @code{make-class} when @var{class} was created.
+@end deffn
+
+@deffn Procedure class-direct-superclasses class
+Returns a list of the direct superclasses of @var{class}. If a
+non-empty @var{direct-superclasses} argument was passed to
+@code{make-class} when @var{class} was created, this list is
+@code{equal?} to that argument. The returned value must not be
+modified.
+@end deffn
+
+@deffn Procedure class-direct-slot-names class
+Returns a list of symbols that are the names of the direct slots of
+@var{class}. This list contains only those slots that were defined in
+the call to @code{make-class} that created @var{class}; it does not
+contain slots that were inherited. The returned value must not be
+modified.
+@end deffn
+
+@deffn Procedure class-precedence-list class
+Returns a list of the superclasses of @var{class}. The order of this
+list is significant: it is the method resolution order. This list will
+always have @var{class} as its first element, and @code{<object>} as its
+last element. The returned value must not be modified.
@end deffn
-@node Predefined Classes, Instances, Classes, Language
+@node Predefined Classes, Record Classes, Class Datatype, Classes
@subsection Predefined Classes
+@cindex predefined classes
+@sc{sos} provides a rich set of predefined classes that can be used to
+specialize methods to any of Scheme's built-in datatypes.
+
@defvr Class <object>
This is the class of all Scheme objects. It has no direct superclasses,
-and all other classes are subclasses of this class. This class is an
-instance of the class @code{<primitive-class>}.
+and all other classes are subclasses of this class.
@end defvr
@defvr Class <instance>
the predicate @code{instance?}.
@end defvr
-@defvr Class <class>
-This is the class of classes. It is a direct subclass of
-@code{<instance>}. The members of this class are the objects that
-satisfy the predicate @code{class?}.
-@end defvr
-
-@defvr Class <generic>
-This is the class of generic procedure instances. It is a direct
-subclass of @code{<instance>}.
-@end defvr
-
-@defvr Class <method>
-This is the class of method objects. It is a direct subclass of
-@code{<instance>}.
-@end defvr
-
@defvr Class <boolean>
@defvrx Class <char>
+@defvrx Class <entity>
@defvrx Class <pair>
@defvrx Class <procedure>
+@defvrx Class <record>
@defvrx Class <string>
@defvrx Class <symbol>
@defvrx Class <vector>
direct subclasses of @code{<object>}. The members of each class are the
objects that satisfy the corresponding predicate; for example, the
members of @code{<procedure>} are the objects that satisfy
-@code{procedure?}. These classes are instances of the class
-@code{<primitive-class>}, except for @code{<procedure>} which is an
-instance of @code{<procedure-class>}.
+@code{procedure?}.
+@end defvr
+
+@defvr Class <generic-procedure>
+This is the class of generic procedure instances. It is a direct
+subclass of @code{<procedure>}.
+@end defvr
+
+@defvr Class <method>
+This is the class of method objects. It is a direct subclass of
+@code{<instance>}.
@end defvr
-@defvr Class <math-object>
-This is the class of mathematical objects. It is a direct subclass of
-@code{<object>}. This class is an abstract class; @code{object-class}
-will not return this class for any object. This class exists in order
-to contain other kinds of mathematical objects besides numbers, in those
-implementations that provide them. For example, the objects defined by
-the @sc{scmutils} algebra system are subclasses of this class.
+@defvr Class <chained-method>
+@defvrx Class <computed-method>
+@defvrx Class <computed-emp>
+These classes specify additional method objects with special properties.
+Each class is a subclass of @code{<method>}.
@end defvr
The following are the classes of Scheme numbers. Note that
These are the classes of the Scheme numeric tower. @code{<number>} is a
direct subclass of @code{<math-object>}, @code{<complex>} is a direct
subclass of @code{<number>}, @code{<real>} is a direct subclass of
-@code{<complex>}, etc. These classes are instances of the class
-@code{<primitive-class>}.
+@code{<complex>}, etc.
@end defvr
@defvr Class <exact>
subclass of @code{<number>}, @code{<exact-complex>} is a direct
subclass of @code{<exact>} and @code{<complex>}, and in general, each is
a direct subclass of preceding class and of the class without the
-@code{exact-} prefix. These classes are instances of the class
-@code{<primitive-class>}.
+@code{exact-} prefix.
@end defvr
@defvr Class <inexact>
subclass of @code{<number>}, @code{<inexact-complex>} is a direct
subclass of @code{<inexact>} and @code{<complex>}, and in general, each
is a direct subclass of preceding class and of the class without the
-@code{inexact-} prefix. These classes are instances of the class
-@code{<primitive-class>}.
+@code{inexact-} prefix.
@end defvr
-@defvr Class <entity>
-This is the class of entity objects. It is a direct subclass of
-@code{<procedure>}. This class is an instance of the class
-@code{<procedure-class>}.
+@node Record Classes, Specializers, Predefined Classes, Classes
+@subsection Record Classes
-This class is defined only in implementations that support entities.
-@end defvr
+@cindex record class
+@sc{sos} allows generic procedures to discriminate on record types.
+This means that a record structure defined by means of
+@code{make-record-type} or @code{define-structure} can be passed as an
+argument to a generic procedure, and the generic procedure can use the
+record's type to determine which method to be invoked.@footnote{If the
+@code{type} option of @code{define-structure} is used, the resulting
+data structure is @emph{not} a record and thus cannot be used in this
+manner.}
+
+In order to support this, @sc{sos} accepts record type descriptors in
+all contexts that accept classes. Additionally, every record type
+descriptor has an associated @sc{sos} class; either the class or the
+record type can be used with equivalent results.
-@defvr Class <record>
-This is the class of record objects. It is a direct subclass of
-@code{<object>}. This class is an instance of the class
-@code{<primitive-class>}.
+@deffn Procedure record-type-class record-type
+@var{Record-type} must be a record type descriptor (in other words, it
+must satisfy the predicate @code{record-type?}). Returns the class
+associated with @var{record-type}.
+@end deffn
-This class is defined only in implementations that support an opaque
-record type.
-@end defvr
+@deffn Procedure record-class record
+@var{Record} must be a record (in other words, it must satisfy the
+predicate @code{record?}). Returns the class associated with
+@var{record}. This is equivalent to
-@node Instances, Slots, Predefined Classes, Language
-@subsection Instances
+@lisp
+(record-type-class (record-type-descriptor @var{record}))
+@end lisp
+@end deffn
-@deffn Procedure make-instance class initarg @dots{}
-Creates and returns a new instance of @var{class}.
+@node Specializers, , Record Classes, Classes
+@subsection Specializers
-The instance is created by a two-step process, which is described here
-to explain the meaning of the @var{initarg}s.
+@cindex specializer
+A @dfn{specializer} is a generalization of a class. A specializer is
+any one of the following:
-@enumerate
+@itemize @bullet
@item
-@code{allocate-instance} is called with @var{class} as its argument to
-allocate a new instance.
+A class.
@item
-@code{initialize-instance} is called with the new instance and the
-@var{initarg}s as its arguments.
-@end enumerate
+A record type, which is equivalent to its associated class.
-@noindent
-In other words, @code{make-instance} might be defined by
+@item
+A union specializer, which is a set of classes.
+@end itemize
-@lisp
-(define (make-instance class . initargs)
- (let ((instance (allocate-instance class)))
- (apply initialize-instance instance initargs)
- instance))
-@end lisp
+A specializer may be used in many contexts where a class is required,
+specifically, as a method specializer (hence the name), as the second
+argument to @code{subclass?}, and elsewhere.
+
+@deffn Procedure specializer? object
+Returns @code{#t} if @var{object} is a specializer, otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn Procedure specializer-classes specializer
+Returns a list of the classes in @var{specializer}. If
+@var{specializer} is a class, the result is a list of that class. If
+@var{specializer} is a record type, the result is a list of the record
+type's class. If @var{specializer} is a union specializer, the result
+is a list of the component classes of the specializer.
+@end deffn
+
+@deffn Procedure specializer=? specializer1 specializer2
+Returns @code{#t} if @var{specializer1} and @var{specializer2} are
+equivalent, otherwise returns @code{#f}. Two specializers are
+equivalent if the lists returned by @code{specializer-classes} contain
+the same elements.
+@end deffn
+
+@deffn Procedure union-specializer specializer @dots{}
+Returns a union specializer consisting of the union of the classes of
+the arguments. This is equivalent to converting all of the specializer
+arguments to sets of classes, then taking the union of those sets.
+@end deffn
+
+@deffn Procedure union-specializer? object
+Returns @code{#t} if @var{object} is a union specializer, otherwise
+returns @code{#f}.
+@end deffn
-Note that the meaning of the @var{initarg}s is completely determined by
-@code{initialize-instance}. The default method for
-@code{initialize-instance} does not accept any @var{initarg}s; if you
-want to pass @var{initarg}s when creating an instance, you must define a
-method on @code{initialize-instance} to accept them.
+@deffn Procedure specializers? object
+Returns @code{#t} if @var{object} is a list of specializers, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn Procedure specializers=? specializers1 specializers2
+@var{Specializers1} and @var{specializers2} must be lists of
+specializers. Returns @code{#t} if @var{specializers1} and
+@var{specializers2} are equivalent, otherwise returns @code{#f}.
+Two specializers lists are equivalent if each of their corresponding
+elements is equivalent.
+@end deffn
-Here is an example showing how this is done:
+@node Instances, Slots, Classes, Object System
+@section Instances
+
+@cindex instance
+An @dfn{instance} is a compound data structure much like a record,
+except that it is defined by a class rather than a record type
+descriptor. Instances are more powerful than records, because their
+representation is designed to support inheritance, while the
+representation of records is not.
+
+@deffn Procedure instance-constructor class slot-names [n-init-args]
+Creates and returns a procedure that, when called, will create and
+return a newly allocated instance of @var{class}.
+
+@var{Class} must be a subclass of @code{<instance>}. @var{Slot-names}
+must be a list of symbols, each of which must be the name of a slot in
+@var{class}. @var{N-init-args} will be described below.
+
+In its basic operation, @code{instance-constructor} works much like
+@code{record-constructor}: the @var{slot-names} argument specifies how
+many arguments the returned constructor accepts, and each of those
+arguments is stored in the corresponding slot of the returned instance.
+Any slots that are not specified in @var{slot-names} are given their
+initial values, as specified by the @code{initial-value} or
+@code{initializer} slot properties; otherwise they are left
+uninitialized.
+
+@cindex initialize-instance
+@findex initialize-instance
+After the new instance is created and its slots filled in, but before it
+is returned, it is passed to the generic procedure
+@code{initialize-instance}. Normally, @code{initialize-instance} does
+nothing, but because it is always called, the programmer can add methods
+to it to specify an initialization that is to be performed on every
+instance of the class.
+
+By default, @code{initialize-instance} is called with one argument, the
+newly created instance. However, the optional argument
+@var{n-init-args} can be used to specify additional arguments that will
+be passed to @code{initialize-instance}.
+
+The way this works is that the returned constructor procedure accepts
+additional arguments after the specified number of slot values, and
+passes these extra arguments to @code{initialize-instance}. When
+@var{n-init-args} is not supplied or is @code{#t}, any number of extra
+arguments are accepted and passed along. When @var{n-init-args} is an
+exact non-negative integer, exactly that number of extra arguments must
+be supplied when the constructor is called. Finally, if
+@var{n-init-args} is the symbol @code{no-initialize-instance}, then the
+constructor accepts no extra arguments and does not call
+@code{initialize-instance} at all; this is desirable when
+@code{initialize-instance} is not needed, because it makes the
+constructor significantly faster.
+
+For notational convenience, @var{n-init-args} may take two other forms.
+First, it may be a list of symbols, which is equivalent to the integer
+that is the length of the list. Second, it may be the symbol
+@code{no-init}, which is an abbreviation for
+@code{no-initialize-instance}.
+
+Note that the default method on @code{initialize-instance} accepts no
+extra arguments and does nothing.
+
+Examples of @code{instance-constructor}:
@lisp
-(define-class <position> (<instance>)
- x
- y)
+@group
+(define-class <simple-reference> (<reference>)
+ (from accessor reference-from)
+ (to accessor reference-to)
+ (cx accessor reference-cx)
+ (cy accessor reference-cy))
+@end group
-(define position-x (slot-accessor <position> 'x))
-(define position-y (slot-accessor <position> 'y))
-(define set-position-x! (slot-modifier <position> 'x))
-(define set-position-y! (slot-modifier <position> 'y))
+@group
+(define make-simple-reference
+ (instance-constructor <simple-reference>
+ '(from to cx cy)
+ 'no-init))
+@end group
-(define-method initialize-instance ((position <position>) x y)
- (set-position-x! position x)
- (set-position-y! position y))
+@group
+(define-class <simple-wirenet> (<wirenet>)
+ (cell accessor wirenet-cell)
+ (wires accessor wirenet-wires
+ modifier set-wirenet-wires!
+ initial-value '()))
+@end group
-(make-instance <position> 3.0 5.3)
+@group
+(define make-simple-wirenet
+ (instance-constructor <simple-wirenet> '(cell)))
+@end group
@end lisp
@end deffn
@code{#f}.
@end deffn
-@deffn Procedure instance-of? object class
-Returns @code{#t} if @var{object} is a general instance of @var{class},
-otherwise returns @code{#f}. In other words, this predicate is true if
-the class of @var{object} is @var{class} or one of its subclasses.
+@deffn Procedure instance-class instance
+Returns the class of @var{instance}. This is faster than
+@code{object-class}, but it works only for instances, and not for other
+objects.
+@end deffn
+
+@deffn Procedure instance-of? object specializer
+Returns @code{#t} if @var{object} is a general instance of
+@var{specializer}, otherwise returns @code{#f}. This is equivalent to
+
+@lisp
+(subclass? (object-class @var{object}) @var{specializer})
+@end lisp
+@end deffn
+
+@deffn Procedure instance-predicate specializer
+Returns a predicate procedure for @var{specializer}. The returned
+procedure accepts one argument and returns @code{#t} if the argument is
+an instance of @var{specializer} and @code{#f} otherwise.
@end deffn
-@node Slots, Generic Procedures, Instances, Language
-@subsection Slots
-@cindex slots
+@node Slots, Generic Procedures, Instances, Object System
+@section Slots
-An object that has @code{<class>} as its metaclass has zero or more
-named slots. The slots of an object are determined by the class of the
-object. Each slot can hold one value. The name of a slot is a symbol.
+@cindex slot
+An instance has zero or more named slots; the name of a slot is a
+symbol. The slots of an instance are determined by its class.
@cindex uninitialized slot
@cindex slot, uninitialized
-When a slot does not have a value, the slot is said to be
-@dfn{uninitialized}. The default initial value for a slot is defined by
-the @code{initializer} slot option.
-
-@cindex instance slot
-@cindex slot, instance
-An @dfn{instance slot} is defined to be a slot that is visible to
-exactly one instance, namely the one in which the slot is allocated.
-The @code{allocation} slot option to @code{make-class} controls the kind
-of slot that is defined. If the value of the @code{allocation} slot
-option is @code{instance}, an instance slot is created.
+Each slot can hold one value. When a slot does not have a value, the
+slot is said to be @dfn{uninitialized}. The default initial value for a
+slot is defined by the @code{initial-value} and @code{initializer} slot
+properties.
@cindex accessibility of slots
A slot is said to be @dfn{accessible} in an instance of a class if the
slot is defined by the class of the instance or is inherited from a
superclass of that class. At most one slot of a given name can be
-accessible in an instance.
+accessible in an instance. Slots are accessed by means of slot-access
+methods (usually generated by @code{make-class}).
-Slots can be accessed in two ways: by use of the primitive slot-access
-procedures @code{slot-accessor}, @code{slot-modifier},
-@code{slot-initpred}, @code{slot-value}, @code{set-slot-value!}, and
-@code{slot-initialized?}; and by use of slot-access methods (usually
-generated by @code{make-class}).
-
-The primitive slot-access procedures can be used with any slot name
-specified in the call to @code{make-class} to access a specific slot
-accessible in an instance of the given class.
+@menu
+* Slot Descriptors::
+* Slot Access Methods::
+* Slot Access Constructors::
+* Slot Access Procedures::
+@end menu
-@cindex accessor, for slot
-@cindex slot accessor
-@cindex modifier, for slot
-@cindex slot modifier
-The procedure @code{make-class} provides slot options for generating
-methods to read and write slots. If an @dfn{accessor} is requested, a
-method is automatically generated for reading the value of the slot. If
-a @dfn{modifier} is requested, a method is automatically generated for
-storing a value into the slot. When an accessor or modifier is
-specified for a slot, the generic procedure to which the generated
-method belongs is directly specified. The procedure specified for the
-accessor takes one argument, the instance. The procedure specified for
-the modifier takes two arguments, the instance and the new value, in
-that order.
+@node Slot Descriptors, Slot Access Methods, Slots, Slots
+@subsection Slot Descriptors
-Slot-access methods can also be generated by the procedures
-@code{slot-accessor-method}, @code{slot-modifier-method}, and
-@code{slot-initpred-method}. These methods may be added to a generic
-procedure by passing them as arguments to @code{add-method}. The methods
-generated by these procedures are identical to those generated by the
-options to @code{make-class}.
+@cindex slot descriptor
+Slots are represented by @dfn{slot descriptors}, which are data
+structures providing information about the slots, such as their name.
+Slot descriptors are stored inside of classes, and may be retrieved from
+there and subsequently inspected.
-Note that @code{slot-value}, @code{set-slot-value!}, and
-@code{slot-initialized?} should not be used in most code, as they are
-inherently slower than the other slot access mechanisms.
+@deffn Procedure class-slots class
+Returns a list of the slot descriptors for @var{class}. This contains
+all slots for @var{class}, both direct slots and inherited slots. The
+returned value must not be modified.
+@end deffn
-To clarify the relationships between the various access mechanisms, here
-are implementations of @code{slot-accessor-method} and
-@code{slot-value}, both in terms of @code{slot-accessor}. These
-implementations are semantically correct, but do not accurately depict
-performance.
+@deffn Procedure class-slot class name error?
+Returns the slot descriptor for the slot named @var{name} in
+@var{class}. If there is no such slot: if @var{error?} is @code{#f},
+returns @code{#f}, otherwise signals an error of type
+@code{condition-type:no-such-slot}.
+@end deffn
-@lisp
-@group
-(define (slot-accessor-method class name)
- (make-leaf-method (list class) (slot-accessor class name)))
+@deffn Procedure slot-descriptor? object
+Returns @code{#t} if @var{object} is a slot descriptor, otherwise
+returns @code{#f}.
+@end deffn
-(define (slot-value instance name)
- ((slot-accessor name) instance))
-@end group
-@end lisp
+@deffn Procedure slot-name slot
+Returns the name of @var{slot}.
+@end deffn
-@deffn Procedure slot-accessor class name
-Returns a procedure of one argument which is an accessor for the slot
-@var{name} in @var{class}; @var{name} may be either a symbol or a slot
-descriptor. The argument to the returned procedure must be an instance
-of @var{class}. When the procedure is called, it returns the contents
-of the slot @var{name} in that instance. If the given instance does not
-have a slot of that name, or if the slot is not initialized, an error is
-signalled.
+@deffn Procedure slot-class slot
+Returns the class of @var{slot}. This is the class with which
+@var{slot} is associated. This is not necessarily the class that
+defines @var{slot}; it could also be a subclass of that class. If the
+slot was returned from @code{class-slots} or @code{class-slot}, then
+this class is the argument passed to that procedure.
@end deffn
-@deffn Procedure slot-modifier class name
-Returns a procedure of two arguments which is a modifier for the slot
-@var{name} in @var{class}; @var{name} may be either a symbol or a slot
-descriptor. The first argument to the returned procedure must be an
-instance of @var{class}, and the second argument may be any object.
-When the procedure is called, it modifies the slot @var{name} in the
-instance to contain the second argument. If the given instance does not
-have a slot of that name, an error is signalled.
+@deffn Procedure slot-properties slot
+Returns an alist of the properties of @var{slot}. This list must not be
+modified.
@end deffn
-@deffn Procedure slot-initpred class name
-Returns a procedure of one argument which is an ``initialized?''@:
-predicate for the slot @var{name} in @var{class}; @var{name} may be
-either a symbol or a slot descriptor. The argument to the returned
-procedure must be an instance of @var{class}. When the procedure is
-called, it returns @code{#t} if the slot @var{name} in that instance is
-initialized, otherwise it returns @code{#f}. If the given instance does
-not have a slot of that name, an error is signalled.
+@deffn Procedure slot-property slot name default
+If @var{slot} has a property named @var{name}, it is returned; otherwise
+@var{default} is returned.
+@end deffn
+
+@deffn Procedure slot-initial-value? slot
+Returns @code{#t} if @var{slot} has an initial value, and @code{#f}
+otherwise. The initial value is specified by the @code{initial-value}
+slot property when a class is made.
+@end deffn
+
+@deffn Procedure slot-initial-value slot
+Returns the initial value for @var{slot}, if it has one; otherwise it
+returns an unspecified value. The initial value is specified by the
+@code{initial-value} slot property when a class is made.
@end deffn
+@deffn Procedure slot-initializer slot
+Returns the initializer for @var{slot}; the initializer is specified by
+the @code{initializer} slot property when a class is made. This is a
+procedure of no arguments that is called to produce an initial value for
+@var{slot}. The result may also be @code{#f} meaning that the slot has
+no initializer.
+@end deffn
+
+@node Slot Access Methods, Slot Access Constructors, Slot Descriptors, Slots
+@subsection Slot Access Methods
+
+@cindex accessor, for slot
+@cindex slot accessor
+@cindex modifier, for slot
+@cindex slot modifier
+The procedure @code{make-class} provides slot properties that generate
+methods to read and write slots. If an @dfn{accessor} is requested, a
+method is automatically generated for reading the value of the slot. If
+a @dfn{modifier} is requested, a method is automatically generated for
+storing a value into the slot. When an accessor or modifier is
+specified for a slot, the generic procedure to which the generated
+method belongs is directly specified. The procedure specified for the
+accessor takes one argument, the instance. The procedure specified for
+the modifier takes two arguments, the instance and the new value, in
+that order.
+
+All of the procedures described here signal an error of type
+@code{condition-type:no-such-slot} if the given class or object does not
+have a slot of the given name.
+
+Slot-access methods can be generated by the procedures
+@code{slot-accessor-method}, @code{slot-modifier-method}, and
+@code{slot-initpred-method}. These methods may be added to a generic
+procedure by passing them as arguments to @code{add-method}. The
+methods generated by these procedures are equivalent to those generated
+by the slot properties in @code{make-class}.
+
@deffn Procedure slot-accessor-method class name
-Returns an accessor method for the slot @var{name} in @var{class}. This
-method has one required argument, an instance of @var{class}, and the
-specializer for that argument is @var{class}. When invoked, the method
-returns the contents of the slot specified by @var{name} in the
-instance. However, if that slot is not initialized, an error is
-signalled instead.
+Returns an accessor method for the slot @var{name} in @var{class}. The
+returned method has one required argument, an instance of @var{class},
+and the specializer for that argument is @var{class}. When invoked, the
+method returns the contents of the slot specified by @var{name} in the
+instance; if the slot is uninitialized, an error of type
+@code{condition-type:uninitialized-slot} is signalled.
+
+@lisp
+@group
+(define-generic get-bar (object))
+
+(add-method get-bar
+ (slot-accessor-method <foo> 'bar))
+@end group
+@end lisp
@end deffn
@deffn Procedure slot-modifier-method class name
-Returns a modifier method for slot @var{name} in @var{class}. This
-method has two required arguments, an instance of @var{class} and an
-object. The specializer for the first argument is @code{class}; the
-second argument is not specialized. When invoked, the method stores the
-second argument in the slot specified by @var{name} in the instance.
+Returns a modifier method for the slot @var{name} in @var{class}. The
+returned method has two required arguments, an instance of @var{class}
+and an object. The specializer for the first argument is @var{class}
+and the second argument is not specialized. When invoked, the method
+stores the second argument in the slot specified by @var{name} in the
+instance.
+
+@lisp
+@group
+(define-generic set-bar! (object bar))
+
+(add-method set-bar!
+ (slot-modifier-method <foo> 'bar))
+@end group
+@end lisp
@end deffn
@deffn Procedure slot-initpred-method class name
-Returns an ``initialized?''@: predicate method for slot @var{name} in
-@var{class}. This method has one required argument, an instance of
-@var{class}, and the specializer for that argument is @code{class}.
-When invoked, the method returns @code{#t} if the slot specified by
-@var{name} is initialized in the instance; otherwise it returns
-@code{#f}.
+Returns an ``initialized?''@: predicate method for the slot @var{name}
+in @var{class}. The returned method has one required argument, an
+instance of @var{class}, and the specializer for that argument is
+@var{class}. When invoked, the method returns @code{#t} if the slot
+specified by @var{name} is initialized in the instance; otherwise it
+returns @code{#f}.
+
+@lisp
+@group
+(define-generic has-bar? (object))
+
+(add-method has-bar?
+ (slot-initpred-method <foo> 'bar))
+@end group
+@end lisp
@end deffn
-@deffn Procedure slot-value instance name
-Returns the contents of the slot @var{name} in @var{instance};
-@var{name} may be either a symbol or a slot descriptor. If
-@var{instance} does not have a slot of that name, or if the slot is not
-initialized, an error is signalled.
+@node Slot Access Constructors, Slot Access Procedures, Slot Access Methods, Slots
+@subsection Slot Access Constructors
+
+For convenience, and for consistency with the record-accessor procedures
+@code{record-accessor} and @code{record-modifier}, each of the above
+method-generating procedures has a corresponding accessor-generator.
+Each of these procedures creates a generic procedure, adds an
+appropriate method to it by calling the corresponding method-generating
+procedure, and returns the generic procedure. Thus, for example, the
+following are equivalent:
+
+@lisp
+@group
+(slot-accessor <foo> 'bar)
+
+(let ((g (make-generic-procedure 1)))
+ (add-method g (slot-accessor-method <foo> 'bar))
+ g)
+@end group
+@end lisp
+
+@deffn Procedure slot-accessor class name
+Returns a generic procedure of one argument that is an accessor for the
+slot @var{name} in @var{class}. The argument to the returned procedure
+must be an instance of @var{class}. When the procedure is called, it
+returns the contents of the slot @var{name} in that instance; if the
+slot is uninitialized, an error of type
+@code{condition-type:uninitialized-slot} is signalled.
@end deffn
-@deffn Procedure set-slot-value! instance name object
-Modifies the slot @var{name} in @var{instance} to contain @var{object};
-@var{name} may be either a symbol or a slot descriptor. If
-@var{instance} does not have a slot of that name, an error is signalled.
+@deffn Procedure slot-modifier class name
+Returns a generic procedure of two arguments that is a modifier for the
+slot @var{name} in @var{class}. The first argument to the returned
+procedure must be an instance of @var{class}, and the second argument
+may be any object. When the procedure is called, it modifies the slot
+@var{name} in the instance to contain the second argument.
@end deffn
-@deffn Procedure slot-initialized? instance name
-Returns @code{#t} if the slot @var{name} in @var{instance} is
-initialized, otherwise returns @code{#f}; @var{name} may be either a
-symbol or a slot descriptor. If @var{instance} does not have a slot of
-that name, an error is signalled.
+@deffn Procedure slot-initpred class name
+Returns a generic procedure of one argument that is an
+``initialized?''@: predicate for the slot @var{name} in @var{class}.
+The argument to the returned procedure must be an instance of
+@var{class}. When the procedure is called, it returns @code{#t} if the
+slot @var{name} in that instance is initialized, otherwise it returns
+@code{#f}.
@end deffn
-A note on errors signalled by the slot-access mechanisms: in the MIT
-Scheme implementation, these errors have specific condition types which
-allow them to be caught and processed by condition handlers. The
-condition signalled when an instance does not have a slot of the given
-name has type @code{condition-type:unbound-slot}. The condition
-signalled by an access to an uninitialized slot has type
-@code{condition-type:uninitialized-instance-slot}. These condition
-types are elements of the following condition type tree:
+@node Slot Access Procedures, , Slot Access Constructors, Slots
+@subsection Slot Access Procedures
+
+Finally, there is another set of three procedures, which access the
+contents of a slot directly, given an instance and a slot name. These
+procedures are very slow by comparison with the above.
+
+However, note the following. You can use these procedures in the body
+of a @code{define-method} special form in an efficient way. If the
+@code{define-method} specifies the correct number of arguments, the body
+of the form contains a call to one of these procedures and nothing else,
+and the specified slot name is quoted, the form is rewritten during
+macro-expansion time as a call to the corresponding method-generating
+procedure. For example, the following are equivalent:
@lisp
-condition-type:slot-error
- condition-type:uninitialized-slot
- condition-type:uninitialized-instance-slot
- condition-type:unbound-slot
+@group
+(define-method p ((v <foo>))
+ (slot-value v 'bar))
+
+(add-method p
+ (slot-accessor-method <foo> 'bar))
+@end group
@end lisp
-@noindent
-If you define a new kind of slot using the meta-object protocol, you
-should create a sub-type of @code{condition-type:uninitialized-slot} to
-signal access to uninitialized slots of that type.
+@deffn Procedure slot-value instance name
+Returns the contents of the slot @var{name} in @var{instance}; if the
+slot is uninitialized, an error of type
+@code{condition-type:uninitialized-slot} is signalled.
+@end deffn
-@node Generic Procedures, Methods, Slots, Language
-@subsection Generic Procedures
+@deffn Procedure set-slot-value! instance name object
+Modifies the slot @var{name} in @var{instance} to contain @var{object}.
+@end deffn
+@deffn Procedure slot-initialized? instance name
+Returns @code{#t} if the slot @var{name} in @var{instance} is
+initialized, otherwise returns @code{#f}.
+@end deffn
+
+@node Generic Procedures, Methods, Slots, Object System
+@section Generic Procedures
+
+@cindex generic procedure
Like an ordinary Scheme procedure, a generic procedure takes arguments,
performs a series of operations, and perhaps returns useful values. An
ordinary procedure has a single body of code that is always executed
-when the procedure is called. A generic procedure has a set of bodies
-of code of which a subset is selected for execution. The selected
-bodies of code and the manner of their combination are determined by the
-classes of one or more of the arguments to the generic procedure.
+when the procedure is called. A generic procedure has a set of multiple
+bodies of code, called methods, from which a subset is selected for
+execution. The selected bodies of code and the manner of their
+combination are determined by the classes of one or more of the
+arguments to the generic procedure.
Ordinary procedures and generic procedures are called with identical
procedure-call syntax.
procedure may be used. In particular, generic procedures satisfy the
predicate @code{procedure?}.
-@deffn Syntax define-generic-procedure name lambda-list
-@deffnx Syntax define-generic-procedure name lambda-list body @dots{}
-Defines @var{name} to be a generic procedure. In the first form,
-@var{lambda-list} is an ordinary parameter list, which is exactly like
-the parameter list in a @code{lambda} special form. This first form of
-@code{define-generic-procedure} expands into
+@menu
+* Generic Procedure Datatype::
+* Method Storage::
+* Effective Method Procedure::
+@end menu
+
+@node Generic Procedure Datatype, Method Storage, Generic Procedures, Generic Procedures
+@subsection Generic Procedure Datatype
+
+The following definitions are used to construct and inspect generic
+procedures.
+
+@deffn Procedure make-generic-procedure arity [name]
+Creates and returns a new generic procedure. The generic procedure
+requires @var{arity} arguments.
+
+@var{Arity} may take one of the following forms. An exact positive
+integer specifies that the procedure will accept exactly that number of
+arguments. A pair of two exact positive integers specifies inclusive
+lower and upper bounds, respectively, on the number of arguments
+accepted; the @sc{cdr} may be @code{#f} indicating no upper bound.
+
+@var{Name} is used for debugging: it is a symbol that has no role in the
+semantics of the generic procedure. @var{Name} may be @code{#f} to
+indicate that the generic procedure is anonymous. If @var{name} is not
+specified, it defaults to @code{#f}.
+
+Examples:
@lisp
+(define foo-bar (make-generic-procedure 2))
+
+(define foo-baz (make-generic-procedure '(1 . 2) 'foo-baz))
+
+(define foo-mum (make-generic-procedure '(1 . #f)))
+@end lisp
+@end deffn
+
+@deffn Syntax define-generic name lambda-list
+Defines @var{name} to be a generic procedure. @var{Lambda-list} is an
+ordinary parameter list, which is exactly like the parameter list in a
+@code{lambda} special form. This expands into
+
+@lisp
+@group
(define @var{name}
- (make-generic-procedure (quote @var{name})
- @var{min-arity}
- @var{max-arity}))
+ (make-generic-procedure @var{arity}
+ (quote @var{name})))
+@end group
@end lisp
@noindent
-where @var{min-arity} and @var{max-arity} are determined from
-@var{lambda-list}.
+where @var{arity} is determined from @var{lambda-list}.
-The second form of @code{define-generic-procedure} has exactly the same
-syntax as @code{define-method}, and expands into a sequence of the first
-form of @code{define-generic-procedure} followed by a
-@code{define-method}.
-@end deffn
+Examples (compare to examples of @code{make-generic-procedure}):
-@deffn Procedure make-generic-procedure name min-arity max-arity
-Creates and returns a new generic procedure. The generic procedure
-requires at least @var{min-arity} arguments, and at most @var{max-arity}
-arguments; if @var{max-arity} is @code{#f}, there is no upper bound on
-the number of arguments accepted.
+@lisp
+(define-generic foo-bar (x y))
-@var{Name} is used for debugging: it is a symbol that has no role in the
-semantics of the generic procedure. Alternatively, @var{name} may be
-@code{#f} to indicate that the generic procedure is anonymous.
+(define-generic foo-baz (x #!optional y))
-@var{Min-arity} must be an exact positive integer. @var{Max-arity}
-must be @code{#f} or an exact integer greater than or equal to
-@var{min-arity}.
+(define-generic foo-mum (x . y))
+@end lisp
@end deffn
@deffn Procedure generic-procedure? object
predicate @code{procedure?}.
@end deffn
-@node Methods, Record Classes, Generic Procedures, Language
-@subsection Methods
+@deffn Procedure generic-procedure-arity generic-procedure
+Returns the arity of @var{generic-procedure}, as specified in the call
+to @code{make-generic-procedure}. The returned arity must not be
+modified.
+@end deffn
+
+@deffn Procedure generic-procedure-name generic-procedure
+Returns the name of @var{generic-procedure}, as specified in the call to
+@code{make-generic-procedure}.
+@end deffn
+
+@node Method Storage, Effective Method Procedure, Generic Procedure Datatype, Generic Procedures
+@subsection Method Storage
+
+Methods are stored in generic procedures. When a generic procedure is
+called, it selects a subset of its stored methods (using
+@code{method-applicable?}), and arranges to invoke one or more of the
+methods as necessary. The following definitions provide the means for
+adding methods to and removing them from a generic procedure.
+
+@deffn Procedure add-method generic-procedure method
+Adds @var{method} to @var{generic-procedure}. If
+@var{generic-procedure} already has a method with the same specializers
+as @var{method}, then the old method is discarded and @var{method} is
+used in its place.
+@end deffn
+
+@deffn Procedure delete-method generic-procedure method
+Removes @var{method} from @var{generic-procedure}. Does nothing if
+@var{generic-procedure} does not contain @var{method}.
+@end deffn
+
+@deffn Procedure add-methods generic-procedure methods
+Adds @var{methods}, which must be a list of methods, to
+@var{generic-procedure}. Equivalent to calling @code{add-method} on
+each method in @var{methods}.
+@end deffn
+
+@deffn Procedure generic-procedure-methods generic-procedure
+Returns a list of the methods contained in @var{generic-procedure}. The
+returned list must not be modified.
+@end deffn
+
+@node Effective Method Procedure, , Method Storage, Generic Procedures
+@subsection Effective Method Procedure
+
+@cindex effective method procedure
+@cindex emp
+When a generic procedure is called, it arranges to invoke a subset of
+its methods. This is done by @dfn{combining} the selected methods into
+an @dfn{effective method procedure}, or @sc{emp}, then tail-recursively
+invoking the @sc{emp}. @code{compute-effective-method-procedure} is the
+procedure that is called to select the applicable methods and combine
+them into an @sc{emp}.
+
+@deffn Procedure compute-effective-method-procedure generic-procedure classes
+Collects the applicable methods of @var{generic-procedure} by calling
+@code{method-applicable?} on each method and on @var{classes}. Combines
+the resulting methods together into an effective method procedure, and
+returns that @sc{emp}.
+@end deffn
+
+@deffn Procedure compute-method generic-procedure classes
+This procedure is like @code{compute-effective-method-procedure}, except
+that it returns the result as a method whose specializers are
+@var{classes}.
+
+@code{compute-method} is equivalent to
+
+@lisp
+@group
+(make-method @var{classes}
+ (compute-effective-method-procedure @var{generic-procedure}
+ @var{classes}))
+@end group
+@end lisp
+@end deffn
+
+@node Methods, Printing, Generic Procedures, Object System
+@section Methods
+
+@cindex method
+A method contains a method procedure and a sequence of @dfn{parameter
+specializers} that specify when the given method is applicable.
+
+A method is not a procedure and cannot be invoked as a procedure.
+Methods are invoked by the effective method procedure when a generic
+procedure is called.
+
+@menu
+* Method Datatype::
+* Method Syntax::
+* Chained Methods::
+* Computed Methods::
+@end menu
+
+@node Method Datatype, Method Syntax, Methods, Methods
+@subsection Method Datatype
+
+The following procedures are used to construct and inspect methods.
+
+@deffn Procedure make-method specializers procedure
+Creates and returns a new method. Note that @var{specializers} may have
+fewer elements than the number of required parameters in
+@var{procedure}; the trailing parameters are considered to be
+specialized by @code{<object>}.
+
+After the returned method is stored in a generic procedure,
+@var{Procedure} is called by the effective method procedure of the
+generic procedure when the generic procedure is called with arguments
+satisfying @var{specializers}. In simple cases, when no method
+combination occurs, @var{procedure} @emph{is} the effective method
+procedure.
+@end deffn
+
+@deffn Procedure method? object
+Returns @code{#t} iff @var{object} is a method, otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn {Generic Procedure} method-specializers method
+Returns the specializers of @var{method}. This list must not be
+modified.
+@end deffn
+
+@deffn {Generic Procedure} method-procedure method
+Returns the procedure of @var{method}.
+@end deffn
-A method object contains a method procedure and a sequence of
-@dfn{parameter specializers} that specify when the given method is
-applicable.
+@deffn Procedure method-applicable? method classes
+This predicate is used to determine the applicability of @var{method}.
+When a method is contained in a generic procedure, and the procedure is
+applied to some arguments, the method is @dfn{applicable} if each
+argument is an instance of the corresponding method specializer, or
+equivalently, if each argument's class is a subclass of the
+corresponding method specializer.
+
+@code{method-applicable?} determines whether @var{method} would be
+applicable if the given arguments had the classes specified by
+@var{classes}. It returns @code{#t} if each element of @var{classes} is
+a subclass of the corresponding specializer of @var{method}, and
+@code{#f} otherwise.
+@end deffn
-A method object is not a procedure and cannot be invoked as a procedure.
-Various mechanisms in @sc{sos} take a method object and invoke its
-method procedure, as is the case when a generic procedure is called.
-When this occurs it is said that the method is invoked or called.
+@node Method Syntax, Chained Methods, Method Datatype, Methods
+@subsection Method Syntax
-A leaf-method object is a special kind of method object that is faster
-to invoke than a regular method object. It gains this speed by
-sacrificing the ``call-next-method'' capability of regular methods (see
-below). Note that the @code{define-method} and @code{method} special
-forms will generate leaf-method objects automatically whenever the
-method body does not contain a free reference to
-@code{call-next-method}.
+The following syntactic forms greatly simplify the definition of
+methods, and of adding them to generic procedures.
@deffn Syntax define-method generic-procedure lambda-list body @dots{}
Defines a method of @var{generic-procedure}. @var{Lambda-list} is like
A @code{define-method} special form expands into the following:
@lisp
+@group
(add-method @var{generic-procedure}
(make-method (list @var{specializer} @dots{})
(lambda (call-next-method . @var{stripped-lambda-list})
@var{body} @dots{})))
+@end group
@end lisp
@noindent
expands into
@lisp
+@group
(add-method add
(make-method (list <integer> <rational>)
(lambda (call-next-method x y) ...)))
+@end group
@end lisp
Note that the list of specializers passed to @code{make-method} will
correspond to the required parameters of the method; the specializer
corresponding to a non-specialized required parameter is
@code{<object>}.
+
+Further note that, within the body of a @code{define-method} special
+form, the free variable @code{call-next-method} is bound to a
+``call-next-method'' procedure (see @code{make-chained-method} for
+details). If the @code{define-method} body refers to this variable, the
+defined method is a chained method, otherwise it is an ordinary method.
@end deffn
@deffn Syntax method lambda-list body @dots{}
@lisp
@group
-(define-method @var{generic-procedure} @var{lambda-list}
- @var{body} @dots{})
+(define-method g ((a <foo>) b)
+ (cons b a))
-(add-method @var{generic-procedure}
- (method @var{lambda-list}
- @var{body} @dots{}))
-@end group
-@end lisp
-@end deffn
-
-@deffn Procedure add-method generic-procedure method
-Adds @var{method} to @var{generic-procedure}. If
-@var{generic-procedure} already has a method with the same specializers
-as @var{method}, then the old method is discarded and @var{method} is
-used in its place.
-@end deffn
+(add-method g
+ (method ((a <foo>) b)
+ (cons b a)))
-@deffn Procedure make-method specializers procedure
-Creates and returns a new method object. @var{Specializers} must be a
-non-null list of class objects. @var{Procedure} should accept one more
-argument than the generic procedure to which this method will be added;
-when called, the first argument will be a ``call-next-method''
-procedure, and the remaining arguments will be the arguments that were
-passed to the generic procedure. The ``call-next-method'' procedure
-accepts arguments, which are passed directly to the next method in place
-of the generic procedure's arguments. It is the method writer's
-responsibility to see that the ``call-next-method'' procedure's
-arguments are sensible.
-
-@quotation
-@strong{Please note:} In Dylan, calling the ``call-next-method''
-procedure with no arguments causes the next method to be called with the
-arguments passed to the calling method; in @sc{sos}, this calls the next
-method with no arguments.
-@end quotation
-@end deffn
-
-@deffn Procedure make-leaf-method specializers procedure
-Creates and returns a new leaf method object. @var{Specializers} must
-be a non-null list of class objects. @var{Procedure} should accept the
-same number of arguments as the generic procedure to which this method
-will be added; @var{procedure} will not be passed a ``call-next-method''
-procedure argument.
-@end deffn
-
-@node Record Classes, , Methods, Language
-@subsection Record Classes
-
-In the MIT Scheme implementation, @sc{sos} allows generic procedures to
-discriminate on record types. This means that a record structure
-defined by means of @code{make-record-type} or @code{define-structure}
-can be passed as an argument to a generic procedure, and the generic
-procedure can use the record's type to determine which method to be
-invoked.@footnote{If the @code{type} option of @code{define-structure}
-is used, the resulting data structure is @emph{not} a record and thus
-cannot be used in this manner.}
-
-In order to support this, @sc{sos} has been extended to accept record
-type descriptors as method specializers. Additionally, every record
-type descriptor has an associated @sc{sos} class; either the class or
-the record type can be used as a specializer with equivalent results.
-
-When a record type descriptor is created, an @sc{sos} class is
-automatically created and associated with the descriptor. This class is
-a direct subclass of @code{<record>}, and is an instance of the
-metaclass @code{<record-class>}. The procedure @code{record-type-class}
-can be used to obtain the class from the record type.
-
-@defvr Class <record-class>
-This is the metaclass of record classes. It is a direct subclass of
-@code{<primitive-class>}.
-@end defvr
-
-@deffn Procedure record-type-class record-type
-@var{Record-type} must be a record type descriptor (in other words, it
-must satisfy the predicate @code{record-type?}). Returns the class
-associated with @var{record-type}.
-@end deffn
-
-@deffn Procedure record-class record
-@var{Record} must be a record (in other words, it must satisfy the
-predicate @code{record?}). Returns the class associated with
-@var{record}. This is equivalent to
-
-@lisp
-(record-type-class (record-type-descriptor @var{record}))
+(add-method g
+ (make-method (list <foo>)
+ (lambda (a b)
+ (cons b a))))
+@end group
@end lisp
@end deffn
-@node Reflective Operations, Meta-Object Protocol, Language, Object System
-@section Reflective Operations
-
-@menu
-* Class Reflectives:: Reflective Operations on Classes
-* Generic Reflectives:: Reflective Operations on Generic Procedures
-* Method Reflectives:: Reflective Operations on Methods
-* Slot Reflectives:: Reflective Operations on Slots
-@end menu
-
-@node Class Reflectives, Generic Reflectives, , Reflective Operations
-@subsection Reflective Operations on Classes
-
-@deffn Procedure class-name class
-Returns the name of @var{class}. This is the @var{name} argument passed
-to @code{make-class} when @var{class} was created.
-@end deffn
-
-@deffn Procedure class-direct-superclasses class
-Returns a list of the direct superclasses of @var{class}. If a
-non-empty @var{direct-superclasses} argument was passed to
-@code{make-class} when @var{class} was created, this list is
-@code{equal?} to that argument.
-
-The returned value must not be modified.
-@end deffn
-
-@deffn Procedure class-precedence-list class
-Returns a list of the superclasses of @var{class}. The order of this
-list is significant: it is the method resolution order. This list will
-always have @var{class} as its first element, and @code{<object>} as its
-last element.
-
-The returned value must not be modified.
-@end deffn
-
-@node Generic Reflectives, Method Reflectives, Class Reflectives, Reflective Operations
-@subsection Reflective Operations on Generic Procedures
-
-Generic procedures have associated objects, called @dfn{generic
-procedure instances}, that contain interesting information about the
-generic procedure. The reflective operations for generic procedures do
-not act directly on generic procedures, but rather on generic procedure
-instances. This division might seem clumsy, but it serves a purpose: it
-separates the accessing of reflective data in the instance from the
-mapping between the generic procedure and its associated instance. This
-is desirable because the mapping between a generic procedure and its
-instance is much slower than an instance slot access. Specifically,
-@code{procedure->generic} is a slow operation.
-
-@deffn Procedure procedure->generic procedure
-If @var{procedure} is a generic procedure, this procedure returns the
-generic procedure instance associated with @var{procedure}. Otherwise,
-it returns @code{#f}.
-@end deffn
-
-@deffn Procedure generic->procedure generic
-Returns the generic procedure associated with @var{generic}.
-@end deffn
-
-@deffn Procedure generic-name generic
-@deffnx Procedure generic-min-arity generic
-@deffnx Procedure generic-max-arity generic
-These procedures return the arguments that were passed to
-@code{make-generic-procedure} to create the generic procedure associated
-with @var{generic}.
-@end deffn
-
-@deffn Procedure generic-methods generic
-Returns a list of the method objects that are contained in the generic
-procedure associated with @var{generic}. This list is in no particular
-order, and it must not be modified.
-@end deffn
-
-@node Method Reflectives, Slot Reflectives, Generic Reflectives, Reflective Operations
-@subsection Reflective Operations on Methods
-
-@deffn Procedure method-specializers method
-Returns the list of specializers of @var{method}. This list must not be
-modified.
-@end deffn
-
-@deffn Procedure method-procedure method
-Returns the procedure of @var{method}. If this is a regular method, the
-returned procedure is the procedure that was passed to
-@code{make-method} when @var{method} was constructed. If this is a leaf
-method, the returned procedure is one that was specially constructed
-when @code{make-leaf-method} was called.
-@end deffn
-
-@deffn Procedure leaf-method-procedure leaf-method
-Returns the procedure of @var{leaf-method}. This is the procedure that
-was passed to @code{make-leaf-method} as an argument when
-@var{leaf-method} was constructed.
-@end deffn
-
-@node Slot Reflectives, , Method Reflectives, Reflective Operations
-@subsection Reflective Operations on Slots
-
-@deffn Procedure slot-descriptors class
-Returns a list of the slot descriptors for the slots of @var{class}.
-This list is in no particular order and must not be modified.
-@end deffn
-
-@deffn Procedure slot-descriptor class name
-Returns the slot descriptor for the slot @var{name} in @var{class}. If
-@var{class} has no slot of that name, an error is signalled.
-@end deffn
-
-@deffn Procedure slot? object
-Returns @code{#t} if @var{object} is a slot descriptor, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn Procedure slot-name slot
-Returns the name of @var{slot}.
-@end deffn
-
-@deffn Procedure slot-class slot
-Returns the class of @var{slot}. This is the class with which
-@var{slot} is associated. This is not necessarily the class that
-defines @var{slot}; it could also be a subclass of that class. If the
-slot was returned by @code{slot-descriptors} or @code{slot-descriptor},
-then this class is the argument passed to that procedure.
-@end deffn
-
-@deffn Procedure slot-allocation slot
-Returns the allocation of @var{slot}. This is a symbol that says how
-the storage for the slot is allocated. For instance slots, this symbol
-is @code{instance}.
-@end deffn
-
-@deffn Procedure slot-initializer slot
-Returns the initializer for @var{slot}. This is a procedure of no
-arguments that is called to produce an initial value for @var{slot}.
-The initializer may also be @code{#f} meaning that the slot has no
-initializer.
+@node Chained Methods, Computed Methods, Method Syntax, Methods
+@subsection Chained Methods
+
+@cindex chained method
+Sometimes it is useful to have a method that adds functionality to
+existing methods. @dfn{Chained methods} provide a mechanism to
+accomplish this. A chained method, when invoked, can call the method
+that would have been called had this method not been defined: it is
+passed a procedure that will call the inherited method. The chained
+method can run arbitrary code both before and after calling the
+inherited method.
+
+@deffn Procedure make-chained-method specializers procedure
+Create and return a chained method. @var{Procedure} must be a procedure
+of one argument that returns a procedure. When the chained method is
+combined, its procedure will be called with one argument, a
+``call-next-method'' procedure; it must then return another procedure
+that will be called when the method is invoked. The
+``call-next-method'' procedure may called by the method procedure at any
+time, which will invoke the next less-specific method. The
+``call-next-method'' procedure must be called with the same number of
+arguments as the method procedure; normally these are the same
+arguments, but that is not required.
@end deffn
-@deffn Procedure slot-plist slot
-Returns the property list of @var{slot}. This list is constructed from
-the class definitions that contributed to @var{slot}'s definition. This
-list must not be modified.
+@deffn Procedure chained-method? object
+Returns @code{#t} if @var{object} is a chained method, otherwise returns
+@code{#f}. Note that every chained method satisfies @code{method?}.
@end deffn
-@deffn Procedure slot-plist-lookup plist name default
-Looks up @var{name} in @var{plist}. If found, the associated datum is
-returned; otherwise, @var{default} is returned. @var{Default} may be
-any object.
-@end deffn
-
-@deffn Procedure slot-property slot name [default]
-Looks up @var{name} in @var{slot}'s property list. If found, the
-associated datum is returned. Otherwise, if @var{default} is given it
-is returned. Otherwise, an error is signalled. @var{Default}, if
-given, may be any object.
-@end deffn
-
-@node Meta-Object Protocol, Miscellany, Reflective Operations, Object System
-@section The Meta-Object Protocol
-
-@menu
-* Generic Invocation Subprotocol::
-* Instantiation Subprotocol::
-* Class Initialization Subprotocol::
-@end menu
-
-@node Generic Invocation Subprotocol, Instantiation Subprotocol, , Meta-Object Protocol
-@subsection The Generic Invocation Subprotocol
-
-@deffn {Generic Procedure} compute-apply-generic generic
-@cindex discriminating procedure
-Computes and returns the @dfn{discriminating procedure} for
-@var{generic}.
-
-This generic procedure is called to determine the discriminating
-procedure for a generic procedure. When a generic procedure is called,
-the @emph{installed} discriminating procedure is called with the full
-set of arguments received by the generic procedure, and must implement
-the behavior of calling the generic procedure: determining the ordered
-set of applicable methods, determining the effective method procedure,
-and running the effective method procedure.
-
-To determine the ordered set of applicable methods, the discriminating
-procedure calls @code{compute-methods}. The discriminating procedure is
-permitted to memoize the value of @code{compute-methods} as follows.
-The discriminating procedure may reuse the list of applicable methods
-without calling @code{compute-methods} again provided that all of the
-following are true:
-
-@enumerate
+@node Computed Methods, , Chained Methods, Methods
+@subsection Computed Methods
+
+@cindex computed method
+A @dfn{computed method} is a powerful mechanism that provides the
+ability to generate methods ``on the fly''. A computed method is like
+an ordinary method, except that its procedure is called during method
+combination, and is passed the classes of the arguments in place of the
+arguments themselves. Based on these classes, the computed method
+returns an ordinary method, which is combined in the usual way.
+
+Note that computed methods and computed @sc{emp}s both satisfy the
+predicate @code{method?}. They are not really methods in that they
+cannot be combined with other methods to form an effective method
+procedure; however, they are treated as methods by procedures such as
+@code{add-method} and @code{method-specializers}.
+
+@deffn Procedure make-computed-method specializers procedure
+Create and return a computed method. @var{Procedure} will be called
+during method combination with the classes of the generic-procedure
+arguments as its arguments. It must return one of the following:
+
+@itemize @bullet
@item
-The generic procedure is being called again with required arguments
-which are instances of the same classes.
+An ordinary method (as returned by @code{make-method} or
+@code{make-chained-method}). The returned method's specializers must be
+restrictions of @var{specializers}, i.e.@: each specializer in the
+returned method must be a subclass of the corresponding specializer in
+@var{specializers}. In the usual case, the returned method's
+specializers are the same as @var{specializers}.
@item
-The generic procedure has not been reinitialized.
+A procedure, which is converted into an ordinary method by calling
+@code{make-method} on @var{specializers} and the returned procedure.
@item
-No method has been added to or removed from the generic procedure.
-
-@item
-For all of the specializers of all the generic procedure's methods which
-are classes, their class precedence lists have not changed.
-
-@item
-For any such memoized value, the class precedence list of the class of
-each of the required arguments has not changed.
-@end enumerate
-
-Determination of the effective method procedure is done by calling
-@code{compute-effective-method-procedure}. When the effective method
-procedure is run, the first applicable method's procedure is called.
-The first argument to that procedure is a ``call-next-method''
-procedure, and the remaining arguments are the arguments that were
-received by the generic procedure. If the first argument calls the
-``call-next-method'' procedure, then the next method in the sequence of
-applicable methods is invoked. The arguments to the next method's
-procedure are a ``call-next-method'' procedure, followed by the
-arguments received by the first method's ``call-next-method'' procedure.
-This process continues until there are no more applicable methods or
-until one of the methods does not call its ``call-next-method''
-procedure.
-
-The generic procedure @code{compute-apply-generic} is called, and its
-result installed, by @code{add-method}.
-
-This procedure is similar to @code{compute-discriminating-function} in
-@sc{clos}.
+@code{#f}, which means that the computed method declines to generate a
+method.
+@end itemize
@end deffn
-@deffn {Generic Procedure} compute-methods generic classes
-@var{Classes} is a non-empty list of class objects. This generic
-procedure returns a list of method objects.
-
-This generic procedure is called to determine the method applicability
-of a generic procedure given only the classes of the required arguments.
-This generic procedure returns that list as its value. The returned list
-of method objects is sorted by precedence order, the most specific
-method coming first. If no methods are applicable to arguments with the
-specified classes, the empty list is returned.
-
-The result of the generic procedure @code{compute-method-more-specific?}
-is used to sort the returned list of methods.
-
-When a generic procedure is invoked, the discriminating procedure must
-determine the ordered list of methods applicable to its arguments.
-Depending on the generic procedure and its arguments, this is done in
-one of two ways: using a memoized value; or calling
-@code{compute-methods}. (Refer to the description of
-@code{compute-apply-generic} for the details of this process.)
-
-The list returned by this generic procedure will not be mutated by the
-implementation. The results are undefined if a program mutates the list
-returned by this generic procedure.
-
-The primary method of this generic procedure is specialized on
-@code{<generic>}. This method can be overridden.
-
-@quotation
-Remarks: This generic procedure exists to allow user extensions which
-alter method lookup rules, but which base the new rules only on the
-classes of the required arguments, to take advantage of the class-based
-method lookup memoization in the implementation.
-
-To get appropriate performance, other kinds of extensions may require
-methods on @code{compute-apply-generic} which implement their own
-memoization scheme.
-@end quotation
-
-This procedure is similar to
-@code{compute-applicable-methods-using-classes} in @sc{clos}.
-@end deffn
-
-@deffn {Generic Procedure} compute-method-more-specific? generic
-This generic procedure computes and returns a procedure of three
-arguments.
-
-This generic procedure is called to determine a sorting predicate which
-can be used by @code{compute-methods} to order a set of methods. The
-sorting predicate is a procedure of three arguments; the first two
-arguments are the methods being compared, and the third argument is a
-list of the classes of the required arguments to the generic procedure
-whose methods are being sorted. The result of the sorting predicate is
-a true value if the first method is more specific than the second method
-(given the required argument classes of the third argument); otherwise,
-the result is @code{#f}.
-
-The arguments passed to the sorting predicate must not be modified.
-
-This generic procedure is called by @code{compute-methods}.
-@end deffn
-
-@deffn {Generic Procedure} compute-effective-method-procedure generic methods
-@cindex effective method procedure
-@var{Methods} must be a list of method objects.
-
-This generic procedure is called to determine the effective method
-procedure from a sorted list of method objects.
-
-An effective method procedure is a procedure that describes how the
-applicable methods are to be combined. It is invoked with the arguments
-passed to the generic procedure associated with @var{generic}, and
-invokes the first applicable method with those arguments, preceded by a
-``call-next-method'' argument, as described earlier for
-@code{compute-apply-generic}.
-
-This generic procedure can be called by the user or the implementation.
-It is called by discriminating procedures whenever a sorted list of
-applicable methods must be converted to an effective method procedure.
-
-The primary method of this generic procedure is specialized on
-@code{<generic>}. This method can be overwritten.
-
-This procedure is similar to @code{compute-effective-method} in
-@sc{clos}.
-@end deffn
-
-@node Instantiation Subprotocol, Class Initialization Subprotocol, Generic Invocation Subprotocol, Meta-Object Protocol
-@subsection The Instantiation Subprotocol
-
-@deffn {Generic Procedure} allocate-instance class
-Called by @code{make-instance} to allocate a new instance; should not be
-called by applications.
-@end deffn
-
-@deffn {Generic Procedure} initialize-instance instance initarg @dots{}
-Called by @code{make-instance} to initialize a newly allocated instance;
-should not be called by applications. @var{initarg}s are the
-@var{initarg}s arguments that were passed to @code{make-instance}. The
-default method for this procedure accepts no @var{initarg}s; if you wish
-to pass arguments to @code{make-instance} you must define a
-corresponding method on @code{initialize-instance} to decipher the
-meaning of those arguments.
+@deffn Procedure computed-method? object
+Returns @code{#t} if @var{object} is a computed method, otherwise
+returns @code{#f}.
@end deffn
-@node Class Initialization Subprotocol, , Instantiation Subprotocol, Meta-Object Protocol
-@subsection The Class Initialization Subprotocol
-
-@deffn {Generic Procedure} compute-precedence-list class
-@end deffn
+@cindex computed emps
+A @dfn{computed @sc{emp}} takes the computed-method mechanism one step
+further. A computed @sc{emp} is like a computed method, except that it
+returns an effective method procedure rather than a method.
+@code{compute-effective-method-procedure} tries each of the applicable
+computed @sc{emp}s, and if exactly one of them returns an @sc{emp}, that
+is the resulting effective method procedure.
+
+@deffn Procedure make-computed-emp key specializers procedure
+Create and return a computed @sc{emp}. @var{Procedure} will be called
+during method combination with the classes of the generic-procedure
+arguments as its arguments. It must return either an @sc{emp} or
+@code{#f}.
-@deffn {Generic Procedure} compute-slots class
+@var{Key} is an arbitrary object that is used to identify the computed
+@sc{emp}. The @var{key} is used by @code{add-method} and
+@code{delete-method} to decide whether two computed @sc{emp}s are
+the same; they are the same if their @var{key}s are @code{equal?}. This
+is necessary because a generic procedure may have more than one computed
+@sc{emp} with the same specializers.
@end deffn
-@deffn {Generic Procedure} compute-slot-descriptor class slots
+@deffn Procedure computed-emp? object
+Returns @code{#t} if @var{object} is a computed @sc{emp}, otherwise
+returns @code{#f}.
@end deffn
-@deffn Procedure make-slot name class allocation initializer plist
-Creates and returns a new slot descriptor. @var{Allocation} must be a
-symbol. @var{Initializer} must be @code{#f} or a procedure of no
-arguments. This should be called only by methods of
-@code{compute-slot-descriptor}.
+@deffn {Generic Procedure} computed-emp-key computed-emp
+Returns the key for @var{computed-emp}.
@end deffn
-@deffn {Generic Procedure} compute-virtual-slot-accessors class slot
-@end deffn
+@node Printing, , Methods, Object System
+@section Printing
-@node Miscellany, , Meta-Object Protocol, Object System
-@section Miscellany
+@cindex printing instances
+The following procedures can be used to define a custom printed
+representation for an instance. It is highly recommended that instances
+be printed by @code{write-instance-helper}, as this ensures a uniform
+appearance for all objects.
-@deffn {Generic Procedure} write-instance instance output-port
-This is called by the default method on @code{unparse-instance} to
-generate the printed representation of @var{instance}. Users should
-define methods on this procedure in preference to
-@code{unparse-instance} since the former is not portable.
+@deffn {Generic Procedure} write-instance instance port
+This is called by the runtime system to generate the printed
+representation of @var{instance}. The methods of this procedure should
+write the representation to @var{port}.
@end deffn
-@deffn {Generic Procedure} unparse-instance instance state
-This is called automatically by the unparser when it tries to print an
-instance; it should not be called by applications. @var{Instance} is
-the instance to be printed, and @var{state} is an unparser-state object.
-
-This generic procedure is only defined in the MIT Scheme implementation.
-@end deffn
+@deffn Procedure write-instance-helper name instance port thunk
+This writes a standardized ``frame'' for a printed representation
+method. It generates the following output on @var{port}:
-@deffn Procedure ppi object
-``Pretty print'' @var{object}. If @var{object} is an instance, the
-slots of the instance are individually pretty printed. Otherwise, the
-procedure @code{pp} is called with @var{object} as its argument.
+@lisp
+#[@var{name} @var{hash-number}@dots{}]
+@end lisp
-This procedure is a kludge that would not be needed if the pretty
-printer had some kind of hook which would enable this behavior to be
-specified.
+@noindent
+where @var{hash-number} is the result of calling @code{hash} on
+@var{instance}, and @dots{} is the output generated by @var{thunk}.
@end deffn
-@defvr Class <primitive-class>
-@end defvr
-
-@defvr Class <procedure-class>
-@end defvr
-
@node Variable Index, Concept Index, Object System, Top
@unnumbered Variable Index
@printindex fn