You are looking at historical revision 30057 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, a wrapper around the actual procedure to be applied. This wrapper is one of the effect-checkers, which accepts a procedure and returns that very procedure after having the procedure's effects 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)

documentation procedure. Shows list of exported symbols. Pre- and post-conditions of a method can be ispected with method-assumptions and method-effects.

method

[syntax] (method [variadic?] (proc-name proc effect-checker) (arg-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 procedure's arguments in sequence, variadic? is a boolean which defaults to #f

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 docs stored in the effect-checkers.

no-checker

[procedure] (no-checker doc . docs)

returns a procedure, which returns its only procedure argument unchecked. The docs describe the procedure's effects.

command-checker

[procedure] (command-checker check doc . docs)

returns a procedure, which checks the side-effects of its only argument, a command, by means of check, returning command after having checked the side-effects. check is a procedures of the same arguments as command returning an even number of values, of type query and compare. 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. The docs describe the procedure's effects and are used for error-messages.

query-checker

[procedure] (query-checker check doc . docs)

returns a procedure, which checks the returned values of its only argument, a query, by means of check, a procedure of the same arguments as query returning a predicate on the query's returned values. The docs describe the procedure's effects and are used for error-messages.

effects-checked?

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

gets or sets a parameter. Without being set no effect checks are performed.

The module multi-methods

multi-methods

[procedure] (multi-methods)

documentation procedure. Prints the sorted list of exported symbols.

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

Nov 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

1.7
tests updated to new version of simple-tests, should have been numbered 0.7
0.6
checkers now procedures, command-checker changed, docu-procedures only export symbols
0.5
query-checker simplyfied
0.4
method and the checkers changed
0.3
syntax and implementation of query-checker changed
0.2
no-checker added
0.1
initial import