You are looking at historical revision 29108 of this page. It may differ significantly from its current revision.

multi-methods

This library provides two modules, methods and multi-methods.

multi-methods are simplified variants of generic functions, while methods are procedures, whose pre- and postconditions are checked.

Both methods and multi-methods are procedures with state, i.e. closures. They are invoked like ordinary procedures, but that results in checking the arguments against predicates in the respective states and invoking the matching procedure, stored in the state as well. The state of a method consists of a list of procedures, the state of a multi-method of a tree of procedures, which makes searching of the multi-methods action comparatively fast.

Contrary to other implementations of generic functions, the state is accessible by the client. Hence the client has control over the place, where a method is to be inserted. This way there is no need to supply type hierarchies: Since more specific procedures are to be inserted before less specific ones, the former are found first.

Since trees of procedures are not really readable by humans, all of them are tagged by name symbols, using the lolevel extend-procedure routine.

These symbols are compared against optional keys in the multi-method-insert! routine. No key means: insert at the end, and a key matching a symbol in the top level of tree: insert before the key, if that key doesn't also match the symbol of the method to be inserted, otherwise step down in the tree and recur.

Note, that methods can be used for two purposes: First they can be inserted into a multi-method at the proper place, second they can be called directly providing some sort of design by contract. This is because preconditions are automatically checked and postconditions can be checked by using the car of the proc-list. This should be a procedure, which when called with no arguments produces documentation and when called with a procedure argument, e.g. the car of the proc-list, returns that very procedure with postconditins checked. But since postcondition checks might be expensive, the application of it can be controlled by the parameter effects-checked?

The module methods

methods

[procedure] (methods [sym])

documentation procedure. If called without arguments prints the list of exported symbols, otherwise the documentation of the exported symbol sym.

method

[syntax] (method [variadic?] (proc-name proc effect-checker doc . docs) (name pred . preds) ...)

constructor. proc ist the actual procedure to be performed, effect-checker one of no-checker query-checker or command-checker, pred and preds are predicates to check the procedures arguments in sequence, variadic? is a boolean which defaults to #f

no-checker

[syntax] (no-checker doc . docs)

returns a procedure, which returns its only procedure argument unchecked.

command-checker

[syntax] (command-checker check0 check1 ...)

returns a procedure, which checks the effects of its only argument, a command, by means of check0 check1 ..., returning its argument after having checked the effects. The checks are procedures of the same arguments as command returning three values, query, compare and doc. The first is the result of calling the query, which accompanies the command (consider the pair car and set-car! for example), the second a comparison routine which compares the result of the query-call before and after the command-call, and the third a list of documentation strings or quoted objects.

query-checker

[syntax] (query-checker (name0 check0 . checks0) (name1 check1 . checks1) ...)

returns a procedure, which checks the results result0 result1 ... of its only argument, a function. (conjoin checki . checksi) is the predicate, which checks resulti.

method?

[procedure] (method? xpr)

type predicate

method-variadic?

[procedure] (method-variadic? meth)

is the method variadic?

method-arity

[procedure] (method-arity meth)

returns the arity of its method argument.

method-name

[procedure] (method-name meth)

returns the name of its method argument.

method-assumptions

[procedure] (method-assumptions meth)

returns the list of names of its method argument's predicates.

method-effects

[procedure] (method-effects meth)

returns the list of names of its method argument's effects.

effects-checked?

[parameter] (effects-checked? [boolean])

gets or sets a parameter.

The module multi-methods

multi-methods

[procedure] (multi-methods [sym])

documentation procedure. If called without arguments prints the list of exported symbols, otherwise the documentation of the exported symbol sym.

multi-method

[syntax] (multi-method var . vars)

constructor. Creates an empty multi-method, whose variadicity is determined by the first insert.

multi-method?

[procedure] (multi-method? xpr)

type predicate.

multi-method-empty?

[procedure] (multi-method-empty? multi)

is the multi-method argument empty?

multi-method-variadic?

[procedure] (multi-method-variadic? multi)

is the multi-method argument variadic?

multi-method-arity

[procedure] (multi-method-arity multi)

returns the arity ot its multi-method argument.

multi-method-keys

[procedure] (multi-method-keys multi key ...)

returs the list of predicate names for checking nth argument, fullfilling key0 ... key(- n 1)

multi-method-insert!

[procedure] (multi-method-insert! multi meth key ...)

updates multi's proc-tree at the appropriate argument level. For example, if no key (or a non-existent key) is given, meth is iserted at the very end. If one key is given, meth is inserted before that very key, provided, that key doesn't match multi's and meth's first predicate name. In that latter case, one recurs with appropriate subtrees.

Requirements

none

Last update

June 16, 2013

Author

Juergen Lorenz

License

Copyright (c) 2013, Juergen Lorenz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission. 
  
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version History

: 0.2 : no-checker added

0.1
initial import