2 Sets of Overloaded Methods
(require (planet "overloads.ss" ("murphy" "multimethod.plt" 2 0))) |
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-method 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-method raises it to indicate that the overloads contain no matching method for signature.
(find-method os signature) → procedure? |
os : overloads? |
signature : any/c |
Retrieves the method implementation from overloads os that matches the given signature best.
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 for the signature. If one is found, the search terminates.
The result of subsequent search steps is later stored in the cache.
The method table is consulted to find a method directly associated with the signature. If one is found, the search terminates here.
A list of possible method implementations is built:
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, or if the first entry sorts strictly before all others, the first entry of the list is used as the method implementation to call and the search terminates here.
If the list has multiple entries but the first one does not sort strictly before all others, an error 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 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.