2 Sets of Overloaded Methods
(require (planet "overloads.ss" ("murphy" "multimethod.plt" 2 1))) |
This module provides procedures to manage sets of overloaded methods. It’s the backend doing all the work behind multimethods.
| ||||||||||||||
default-signature : any/c = #f | ||||||||||||||
ref-hierarchy : (-> hierarchy?) = global-hierarchy |
Creates a new overload set. default-signature is a default signature that is looked up in the method tables if the one passed to find-methods doesn’t match any implementation. ref-hierarchy is a procedure yielding the value hierarchy to be used by signature comparisons, it defaults to global-hierarchy, ie. the default behaviour is to read the current value of the global hierarchy parameter every time the hierarchy is needed.
(overloads? v) → boolean? |
v : any/c |
Checks whether the given object is an overload set.
(overloads-default-signature m) → any/c |
m : overloads? |
Retrieves the default signature of an overload set.
(set-method os signature method) → overloads? |
os : overloads? |
signature : any/c |
method : procedure? |
Takes the overloads os and transforms them into new overloads that map the given signature to the method implementation method.
Any existing mapping for the given signature is replaced.
(remove-method os signature) → overloads? |
os : overloads? |
signature : any/c |
Takes the overloads os and transforms them into new overloads that have no direct mapping for the given signature to any method implementation.
(prefer-method os signature-a signature-b) → overloads? |
os : overloads? |
signature-a : any/c |
signature-b : any/c |
Takes the overloads os and transforms them into new overloads that prefer dispatching via signature-a over dispatching via signature-b.
(unprefer-method os signature-a signature-b) → overloads? |
os : overloads? |
signature-a : any/c |
signature-b : any/c |
Takes the overloads os and transforms them into new overloads that do not prefer dispatching via signature-a over dispatching via signature-b.
(struct (exn:fail:multimethod exn:fail) (overloads signature)) |
overloads : overloads? |
signature : any/c |
An exception raised to signal a problem with multimethod dispatch. find-methods raises it to indicate that the overloads contain no matching method for signature.
(find-methods os signature) → (listof procedure?) |
os : overloads? |
signature : any/c |
Retrieves all method implementations from overloads os that match the given signature and that can be strictly ordered by specificity or preference.
The method lookup works as follows:
The current hierarchy used by the overload set is retrieved using the getter procedure passed to make-overloads. If this value changed since the last time the overload set was asked to find a method, the new value is stored and the dispatching cache of the overload set is cleared, ie. it is reset to the same state in which it was created.
The dispatching cache is consulted to find a method list for the signature. If one is found, the search terminates.
The result of subsequent search steps is later stored in the cache.
A list of possible method implementations is built:
The method table is consulted to find a method directly associated with the signature.
All ancestors of the signature registered in the hierarchy used by the overload set are retrieved. Then any methods associated to those ancestor signatures are fetched from the method table.
If the signature satisfies class?, interface? or dict?, the whole method table is scanned for mappings from candidate signatures that are ancestors of the reference signature as determined by derived?.
All method implementations found in this way are sorted by their signatures. A signature sorts before another if one of the following conditions is met:
The first signature is derived? from the second one.
The first signature is registered as preferred to the second one.
There is a registered preference such that the first signature is derived? from the preferred signature while the less preferred signature is derived? from the second signature.
If the resulting sorted list has exactly one entry, this list of one method is used and the search terminates here.
If the list has multiple entries, the longest prefix of the list that is strictly sorted is determined. If this prefix is not empty, it is used as the list of methods and the search terminates here.
If the list has multiple entries but the first one does not sort strictly before all others, an exception of type exn:fail:multimethod is raised indicating ambiguous methods. You can resolve this situation by defining more specific methods or by registering preferences.
If no method implementation was found so far, the search is retried from the second step using not the original signature, but the overload set’s default signature.
If all steps up to now have failed to find a method. An exception of type exn:fail:multimethod is raised indicating a lack of applicable method implementations.