[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5. Methods

A method contains a method procedure and a sequence of 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.

5.1 Method Datatype  
5.2 Method Syntax  
5.3 Chained Methods  
5.4 Computed Methods  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1 Method Datatype

The following procedures are used to construct and inspect methods.

Procedure: make-method specializers procedure
Creates and returns a new method. Note that specializers may have fewer elements than the number of required parameters in procedure; the trailing parameters are considered to be specialized by <object>.

After the returned method is stored in a generic procedure, Procedure is called by the effective method procedure of the generic procedure when the generic procedure is called with arguments satisfying specializers. In simple cases, when no method combination occurs, procedure is the effective method procedure.

Procedure: method? object
Returns #t iff object is a method, otherwise returns #f.

Generic Procedure: method-specializers method
Returns the specializers of method. This list must not be modified.

Generic Procedure: method-procedure method
Returns the procedure of method.

Procedure: method-applicable? method classes
This predicate is used to determine the applicability of method. When a method is contained in a generic procedure, and the procedure is applied to some arguments, the method is 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.

method-applicable? determines whether method would be applicable if the given arguments had the classes specified by classes. It returns #t if each element of classes is a subclass of the corresponding specializer of method, and #f otherwise.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2 Method Syntax

The following syntactic forms greatly simplify the definition of methods, and of adding them to generic procedures.

Syntax: define-method generic-procedure lambda-list body ...
Defines a method of generic-procedure. Lambda-list is like the parameter list of a lambda special form, except that the required parameters may have associated specializers. A parameter with an associated specializer is written as a list of two elements: the first element is the parameter's name, and the second element is an expression that evaluates to a class.

Lambda-list must contain at least one required parameter, and at least one required parameter must be specialized.

A define-method special form expands into the following:

 
(add-method generic-procedure
  (make-method (list specializer ...)
    (lambda (call-next-method . stripped-lambda-list)
      body ...)))

where stripped-lambda-list is lambda-list with the specialized parameters replaced by their names, and the specializers are the corresponding expressions from the specialized parameters. If necessary, the specializers are interspersed with references to <object> in order to make them occur in the correct position in the sequence.

For example,

 
(define-method add ((x <integer>) (y <rational>)) ...)

expands into

 
(add-method add
  (make-method (list <integer> <rational>)
    (lambda (call-next-method x y) ...)))

Note that the list of specializers passed to make-method will correspond to the required parameters of the method; the specializer corresponding to a non-specialized required parameter is <object>.

Further note that, within the body of a define-method special form, the free variable call-next-method is bound to a "call-next-method" procedure (see make-chained-method for details). If the define-method body refers to this variable, the defined method is a chained method, otherwise it is an ordinary method.

Syntax: method lambda-list body ...
This special form evaluates to an anonymous method in the same way that lambda evaluates to an anonymous procedure. Lambda-list and body have exactly the same syntax and semantics as the corresponding parts of define-method. Note that the following are completely equivalent:

 
(define-method g ((a <foo>) b)
  (cons b a))

(add-method g
  (method ((a <foo>) b)
    (cons b a)))

(add-method g
  (make-method (list <foo>)
    (lambda (a b)
      (cons b a))))


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.3 Chained Methods

Sometimes it is useful to have a method that adds functionality to existing methods. 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.

Procedure: make-chained-method specializers procedure
Create and return a chained method. 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.

Procedure: chained-method? object
Returns #t if object is a chained method, otherwise returns #f. Note that every chained method satisfies method?.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.4 Computed Methods

A 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 EMPs both satisfy the predicate 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 add-method and method-specializers.

Procedure: make-computed-method specializers procedure
Create and return a computed method. 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:

Procedure: computed-method? object
Returns #t if object is a computed method, otherwise returns #f.

A computed EMP takes the computed-method mechanism one step further. A computed EMP is like a computed method, except that it returns an effective method procedure rather than a method. compute-effective-method-procedure tries each of the applicable computed EMPs, and if exactly one of them returns an EMP, that is the resulting effective method procedure.

Procedure: make-computed-emp key specializers procedure
Create and return a computed EMP. Procedure will be called during method combination with the classes of the generic-procedure arguments as its arguments. It must return either an EMP or #f.

Key is an arbitrary object that is used to identify the computed EMP. The key is used by add-method and delete-method to decide whether two computed EMPs are the same; they are the same if their keys are equal?. This is necessary because a generic procedure may have more than one computed EMP with the same specializers.

Procedure: computed-emp? object
Returns #t if object is a computed EMP, otherwise returns #f.

Generic Procedure: computed-emp-key computed-emp
Returns the key for computed-emp.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Chris Hanson on July, 18 2001 using texi2html