The SOS Reference Manual: Methods

[ < ] | [ > ] |  | [ << ] | [ 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 form greatly simplifies 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.

[ < ] | [ > ] |  | [ << ] | [ 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:

  - An ordinary method (as returned by `make-method` or `make-chained-method`). The returned method's specializers must be restrictions of specializers, i.e. each specializer in the returned method must be a subclass of the corresponding specializer in specializers. In the usual case, the returned method's specializers are the same as specializers.

  - A procedure, which is converted into an ordinary method by calling `make-method` on specializers and the returned procedure.

  - `#f`, which means that the computed method declines to generate a method.

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 September, 19 2003 using texi2html