From: Chris Hanson Date: Wed, 24 Feb 1993 05:52:51 +0000 (+0000) Subject: Update to match revision 1.7 of "sos.scm". Flesh out part of the X-Git-Tag: 20090517-FFI~8475 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=b4a686ea53031d5da8f125ddc92da1c8e5c2451c;p=mit-scheme.git Update to match revision 1.7 of "sos.scm". Flesh out part of the meta-object protocol by stealing text from the CLOS spec. --- diff --git a/v7/doc/sos/sos.texinfo b/v7/doc/sos/sos.texinfo index e860102d1..4ceed641e 100644 --- a/v7/doc/sos/sos.texinfo +++ b/v7/doc/sos/sos.texinfo @@ -6,10 +6,10 @@ @setchapternewpage odd @synindex vr fn -@c $Id: sos.texinfo,v 1.1 1993/02/23 23:09:59 cph Exp $ +@c $Id: sos.texinfo,v 1.2 1993/02/24 05:52:51 cph Exp $ @set TITLE The SOS Reference Manual -@set EDITION 1.1 +@set EDITION 1.2 @set UPDATED 21 February 1993 @set UPDATE-MONTH February 1993 @@ -350,13 +350,14 @@ the following forms: @noindent where @var{name} is a symbol, and @var{plist} is a property list. The -first of these two forms is equivalent to the second with a empty +first of these two forms is equivalent to the second with an empty @var{plist}. -Each of the elements of @var{direct-slots} defines one slot with the -given name. @var{Plist} is used to describe additional properties of +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 are recognized: +@code{compute-slot-descriptor}; by default these properties are +recognized: @table @code @item initializer @@ -378,6 +379,10 @@ an accessor method for this slot to the procedure. This property specifies a generic procedure; @code{make-class} will add a modifier method for this slot to the procedure. +@item initpred +This property specifies a generic procedure; @code{make-class} will add +an ``initialized?'' predicate method for this slot to the procedure. + @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 @@ -448,14 +453,53 @@ This is the class of method objects. It is a direct subclass of @defvrx Class @defvrx Class @defvrx Class -These are the classes of their respective Scheme objects. They -are all direct subclasses of @code{}, except for @code{} -which is a direct subclass of @code{}. The members of each -class are the objects that satisfy the corresponding predicate; for -example, the members of @code{} are the objects that satisfy +These are the classes of their respective Scheme objects. They are all +direct subclasses of @code{}. The members of each class are the +objects that satisfy the corresponding predicate; for example, the +members of @code{} are the objects that satisfy @code{procedure?}. @end defvr +The following are the classes of Scheme numbers. Note that +@code{object-class} will never return one of these classes; instead it +returns an implementation-specific class that is associated with a +particular numeric representation. The implementation-specific class is +a subclass of one or more of these implementation-independent classes, +so you should use these classes for specialization. + +@defvr Class +@defvrx Class +@defvrx Class +@defvrx Class +These are the classes of the Scheme numeric tower. @code{} is +a direct subclass of @code{}, @code{} is a direct subclass +of @code{}, etc. +@end defvr + +@defvr Class +@defvrx Class +@defvrx Class +@defvrx Class +@defvrx Class +These are the classes of exact numbers. @code{} is a direct +subclass of @code{}, @code{} is a direct +subclass of @code{} and @code{}, and in general, each is +a direct subclass of preceding class and of the class without the +@code{exact-} prefix. +@end defvr + +@defvr Class +@defvrx Class +@defvrx Class +@defvrx Class +@defvrx Class +These are the classes of inexact numbers. @code{} is a direct +subclass of @code{}, @code{} is a direct +subclass of @code{} and @code{}, and in general, each +is a direct subclass of preceding class and of the class without the +@code{inexact-} prefix. +@end defvr + @defvr Class This is the class of entity objects. It is a direct subclass of @code{}. This class is defined only in @sc{mit} Scheme. @@ -586,51 +630,105 @@ accessor takes one argument, the instance. The procedure specified for the modifier takes two arguments, the instance and the new value, in that order. -Note that it is preferable to use @code{slot-accessor} and -@code{slot-modifier} rather than @code{slot-value} and -@code{set-slot-value!}, because the former incorporate a caching -mechanism that makes them much more efficient than the latter. +Accessor and modifier methods can also be generated by the procedures +@code{slot-accessor-method} and @code{slot-modifier-method}, +respectively. These methods may be added to a generic function by +passing them as arguments to @code{add-method}. The methods generated +by these procedures are completely equivalent to those generated by the +options to @code{make-class}. + +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. + +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. + +@lisp +(define (slot-accessor-method slot) + (make-method + (list (slot-class slot)) + (let ((accessor (slot-accessor (slot-name slot)))) + (lambda (call-next-method instance) + (accessor instance))))) + +(define (slot-value instance name) + ((slot-accessor name) instance)) +@end lisp @deffn Procedure slot-accessor name Returns a procedure of one argument which is an accessor for the slot -@var{name}. The argument to this procedure must be an instance. When -the procedure is called, it returns the contents of the slot @var{name} -in that instance. If the given instance does not have such a slot, or -if the slot is not initialized, an error is signalled. +@var{name}; @var{name} may be either a symbol or a slot descriptor. The +argument to this procedure must be an instance. When the procedure is +called, it returns the contents of the slot @var{name} in that instance. +If the given instance does not have such a slot, or if the slot is not +initialized, an error is signalled. @end deffn @deffn Procedure slot-modifier name Returns a procedure of two arguments which is a modifier for the slot -@var{name}. This first argument to this procedure must be an instance, -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 such a slot, an -error is signalled. -@end deffn - -@deffn Procedure slot-initialized-predicate name -Returns a procedure of one argument which is a predicate for the slot -@var{name}. The argument to this procedure must be an instance. When -the procedure is called, it return @code{#t} if the slot @var{name} in -that instance is initialized, otherwise it returns @code{#f}. If the +@var{name}; @var{name} may be either a symbol or a slot descriptor. +This first argument to this procedure must be an instance, 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 such a slot, an error is +signalled. +@end deffn + +@deffn Procedure slot-initpred name +Returns a procedure of one argument which is an ``initialized?'' +predicate for the slot @var{name}; @var{name} may be either a symbol or +a slot descriptor. The argument to this procedure must be an instance. +When the procedure is called, it return @code{#t} if the slot @var{name} +in that instance is initialized, otherwise it returns @code{#f}. If the given instance does not have such a slot, an error is signalled. @end deffn +@deffn Procedure slot-accessor-method slot +Returns an accessor method for @var{slot}. This method has one required +argument, an instance, and the specializer for that argument is the +@code{slot-class} of @var{slot}. When invoked, the method returns the +contents of the slot specified by @var{slot} in the instance. However, +if that slot is not initialized, an error is signalled instead. +@end deffn + +@deffn Procedure slot-modifier-method slot +Returns a modifier method for @var{slot}. This method has two required +arguments, an instance and an object. The specializer for the first +argument is the @code{slot-class} of @var{slot}; the second argument is +not specialized. When invoked, the method stores the second argument in +the slot specified by @var{slot} in the instance. +@end deffn + +@deffn Procedure slot-initpred-method slot +Returns an ``initialized?'' predicate method for @var{slot}. This +method has one required argument, an instance, and the specializer for +that argument is the @code{slot-class} of @var{slot}. When invoked, the +method returns @code{#t} if the slot specified by @var{slot} is +initialized in the instance; otherwise it returns @code{#f}. +@end deffn + @deffn Procedure slot-value instance name -Returns the contents of the slot @var{name} in @var{instance}. If +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 such a slot, or if the slot is not initialized, an error is signalled. @end deffn @deffn Procedure set-slot-value! instance name object -Modifies the slot @var{name} in @var{instance} to contain @var{object}. -If @var{instance} does not have such a slot, an error is signalled. +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 such a slot, an error is signalled. @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}. If @var{instance} does not -have such a slot, an error is signalled. +initialized, otherwise returns @code{#f}; @var{name} may be either a +symbol or a slot descriptor. If @var{instance} does not have such a +slot, an error is signalled. @end deffn @node Generic Procedures, Methods, Slots, Language @@ -640,16 +738,17 @@ 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 clde of which a subset is selected for execution. The selected +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. Ordinary procedures and generic procedures are called with identical procedure-call syntax. -Generic procedures are tru procedures that can be passed as arguments, +Generic procedures are true procedures that can be passed as arguments, returned as values, and otherwise used in all the ways an ordinary -procedure may be used. +procedure may be used. In particular, generic procedures satisfy the +predicate @code{procedure?}. @deffn Syntax define-generic-procedure name lambda-list Defines @var{name} to be a generic procedure. @var{Lambda-list} is an @@ -675,13 +774,13 @@ 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. -@var{Min-arity} must be an exact nonnegative integer. @var{Max-arity} -must be @code{#f} or an exact integer greater than or equal to -@var{min-arity}. - @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 has no name. +@code{#f} to indicate that the generic procedure is anonymous. + +@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}. @end deffn @deffn Procedure generic-procedure? object @@ -726,7 +825,9 @@ A @code{define-method} special form expands into the following: where @var{stripped-lambda-list} is @var{lambda-list} with the specialized parameters replaced by their names, and the @var{specializer}s are the corresponding expressions from the -specialized parameters. +specialized parameters. If necessary, the @var{specializer}s are +interspersed with references to @code{} in order to make them +occur in the correct position in the sequence. For example, @@ -765,14 +866,14 @@ 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'' arguments are -sensible. +responsibility to see that the ``call-next-method'' procedure's +arguments are sensible. @quotation -@strong{Please note:} In Dylan, calling the ``call-next-method'' with no -arguments causes the next method to be called with the arguments passed -to the calling method; in this system, this calls the next method with -no arguments. +@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 this system, this calls the +next method with no arguments. @end quotation @end deffn @@ -795,9 +896,10 @@ 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-null -@var{direct-superclasses} argument was passed to @code{make-class} when -@var{class} was created, this list is @code{equal?} to that argument. +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 @@ -816,12 +918,20 @@ The returned value must not be modified. Generic procedures have associated objects, called @dfn{generic procedure instances}, that contain interesting information about the -generic procedure. +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. More +specifically, @code{procedure->generic} is much slower than +@code{generic-min-arity}. @deffn Procedure procedure->generic procedure -If @var{procedure} is a generic procedure, this returns the generic -procedure instance associated with @var{procedure}. Otherwise, returns -@code{#f}. +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 @@ -894,8 +1004,8 @@ is @code{instance}. @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 should not -be initialized. +The initializer may also be @code{#f} meaning that the slot has no +initializer. @end deffn @deffn Procedure slot-plist slot @@ -904,10 +1014,17 @@ the class definitions that contributed to @var{slot}'s definition. This list must not be modified. @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. +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 @@ -923,15 +1040,151 @@ is returned. Otherwise, an error is signalled. @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 +@item +The generic procedure is being called again with required arguments +which are instances of the same classes. + +@item +The generic procedure has not been reinitialized. + +@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}. @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{}. 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{}. 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 @@ -958,6 +1211,9 @@ meaning of those arguments. @deffn {Generic Procedure} compute-precedence-list class @end deffn +@deffn {Generic Procedure} compute-slots class +@end deffn + @deffn {Generic Procedure} compute-slot-descriptor class slots @end deffn @@ -968,21 +1224,12 @@ arguments. This should be called only by methods of @code{compute-slot-descriptor}. @end deffn -@deffn {Generic Procedure} compute-slots class -@end deffn - @deffn {Generic Procedure} compute-virtual-slot-accessors class slot @end deffn @node Miscellany, , Meta-Object Protocol, Object System @section Miscellany -@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. -@end deffn - @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 @@ -990,7 +1237,22 @@ define methods on this procedure in preference to @code{unparse-instance} since the former is not portable. @end deffn -@deffn Procedure ppi instance +@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 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. + +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. @end deffn @defvr Class