palisades.lakes.multimethods.core
Faster multimethod method lookup.
defmethod
macro
added in faster-multimethods 0.0.0
(defmethod multifn v & fn-tail)
Creates and installs a new method for multifn
associated with dispatch value v
.
-
multifn
: an instance ofpalisades.lakes.multimethods.java.MultiFn
, created with palisades.lakes.multimethods.core/defmulti. -
v
: satisfies(legal-dispatch-value? multifn v)
. -
fn-tail
: one or more of arglist plus function body, which are passed tofn
to generate the method function. Note that signatures only support single arity method functions.
Throws an exception if v
is not a legal dispatch value for multifn
.
Warning: mutates multifn
.
Note: unlike defmulti, re-evaluating defmethod will replace any existing method for v
.
Note: defmethod can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
defmulti
macro
added in faster-multimethods 0.0.0
(defmulti mm-name docstring? attr-map? dispatch-fn & options)
Creates a new multimethod (an instance of palisades.lakes.multimethods.java.MultiFn
) named mm-name
that uses dispatch-fn
to generate dispatch values.
-
mm-name
: a namespace qualifiedSymbol
. TheMultFn
will be the value of theVar
with that name. -
docstring?
(optional): documentation string used as the:doc
metadata on#'mm-name
. -
attr-map?
(optional): more metadata for#'mm-name
. -
dispatch-fn
an instance ofclojure.lang.IFn
that returns legal dispatch values when applied to (supported) arguments passed to theMultiFn
. There is no check that thedispatch-fn
returns legal values. You may use legal-dispatch-value? in thedispatch-fn
to validate the returned value, perhaps only during debugging if performance is critical. -
options
(optional): are key-value pairs and may be one of:-
:hierarchy
:false
,nil
, or aVar
whose value is a hierarchy. Used for method lookup when the dispatch values are or contain namespace-qualified instances ofNamed
.See multimethods and hierarchies for information on how to create and modify hierarchies.
If the
:hierarchy
is not supplied, it defaults to#'clojure.core/global-hierarchy
.If
:hierarchy
is supplied and its value isnil
orfalse
, then onlyClass
andSignature
dispatch values are permitted, and method lookup is optimized for that case.Otherwise the value of the
:hierarchy
option must be aVar
(i.e. via the Var-quote dispatch macro #’ or the var special form) holding a hashmap created withclojure.core/make-hierarchy
.Warning: Multimethods that use hierarchies depend on mutable shared state. It is possible for someone else to modify the shared hierarchy in a way that breaks method lookup.
Warning: the Clojure hierarchy functions behave differently for the default
#'clojure.core/global-hierarchy
versus a custom local hierarchy. Updates to the global hierarchy callalter-var-root
on#'clojure.core/global-hierarchy
, mutating shared state. Updates to a custom hierarchy return a new hashmap; it’s left to the caller to rebind anyVar
which might be pointing to the original hierarchy. If you use a local hierarchy, and modify it after the multimethod is created, it will have no effect unless you explicitly rebind theVar
that was passed to defmulti. This is an easy mistake to make, and not so easy to see what’s wrong.Note: like the Clojure implementation, there is no way to determine what hierarchy is used by an existing multimethod, which might be useful if you wanted to ensure a new multimethod had the same inheritance behavior as an existing one. This may change in a future release.
-
:default
: The default dispatch value, defaults to:default
. Not supported, and an exception is thrown, when:hierarchy false
or:hierarchy nil
and the value of:default
is notfalse
ornil
.
-
Warning: If #'mm-name
is already defined and its value is a MultiFn
, defmulti silently does nothing. This is the Clojure 1.8.0 defmulti behavior. This may change in a future release.
(This seems to me like bad answer to the problem of accidentally re-evaluating a given defmulti and wiping out all the methods. I think a better design would make MultiFn
effectively immutable. defmulti, defmethod, etc., would return new instances which are updates of the existing instance, and call alter-var-root
to update the value of #'mm-name
. This, I believe, is what defn
does.)
dominates<
added in faster-multimethods 0.0.8
(dominates< multifn x y)
Transitive extension of isa< with pairs created by calls to prefer-method.
(dominates< multifn x y)
is eqiuvalent to (and (dominates<= multifn x y) (not= x y))
.
Throws an exception if x
and y
are not legal dispatch values for multifn
.
Not used in method lookup, which is implemented in Java, but may be useful for debugging.
dominates<=
added in faster-multimethods 0.0.8
(dominates<= multifn x y)
Transitive extension of isa<= with pairs created by calls to prefer-method.
(dominates<= multifn x y)
is eqiuvalent to (or (dominates< multifn x y) (= x y))
.
Throws an exception if x
and y
are not legal dispatch values for multifn
.
Not used in method lookup, which is implemented in Java, but may be useful for debugging.
get-method
added in faster-multimethods 0.0.0
(get-method multifn v)
Given a multimethod multifn
and a dispatch value v
, returns the defined method function that would be applied to any arglist that resulted in the dispatch value v
. If there are no methods that are applicable to v
, returns nil
.
Note: get-method can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
Warning: Does NOT throw an exception if v
is an illegal dispatch value for multifn
; returns nil
in that case.
isa<
added in faster-multimethods 0.0.8
(isa< multifn x y)
Extension of clojure.core/isa?
, for a particular multimethod, to all legal dispatch values.
(isa< multifn x y)
is eqiuvalent to (and (isa<= multifn x y) (not= x y))
.
isa< implies dominates<.
Throws an exception if x
and y
are not legal dispatch values for multifn
.
Not used in method lookup, which is implemented in Java, but may be useful for debugging.
isa<=
added in faster-multimethods 0.0.8
(isa<= multifn x y)
Extension of clojure.core/isa?
, for a particular multimethod, to all legal dispatch values.
(isa<= multifn x y)
is eqiuvalent to (or (isa< multifn x y) (= x y))
. isa<= implies dominates<=.
Throws an exception if x
and y
are not legal dispatch values for multifn
.
Not used in method lookup, which is implemented in Java, but may be useful for debugging.
legal-dispatch-value?
added in faster-multimethods 0.0.9
(legal-dispatch-value? multifn v)
Is v
a legal dispatch value for multifn
?
All multimethods accept classes and signatures. Multimethods with a hierarchy also accept namespace qualified symbols and keywords, the special non-namespace-qualified keyword :default
, and vectors whose elements are all legal dispatch values, permitting arbitrary nesting.
Note: legal-dispatch-value? can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
methods
added in faster-multimethods 0.0.0
(methods multifn)
Given a multimethod, returns a map of dispatch values -> method functions.
Note: methods can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
prefer-method
added in faster-multimethods 0.0.0
(prefer-method multifn x y)
Causes the multimethod to prefer matches of x
over y
when there is a conflict.
Throws an exception if x
and y
are not legal dispatch values for multifn
.
Note: prefer-method can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
Warning: mutates multifn
.
prefers
added in faster-multimethods 0.0.0
(prefers multifn)
Given a multimethod, returns a map of more preferred dispatch value -> set of less preferred dispatch values.
Note: prefers can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
remove-all-methods
added in faster-multimethods 0.0.0
(remove-all-methods multifn)
Removes all of the methods of multimethod.
Note: remove-all-methods can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
Warning: despite the name, this actually removes all the preferences, in addition to the methods, and clears the cache.
Warning: mutates multifn
.
remove-method
added in faster-multimethods 0.0.0
(remove-method multifn v)
Removes the method of multimethod associated with v
. Does nothing if no method is defined for v
.
Throws an exception if v
is not legal dispatch value for multifn
.
Note: remove-method can only be used with multimethods defined with palisades.lakes.multimethods.core/defmulti.
Warning: mutates multifn
.
signature
added in faster-multimethods 0.0.9
(signature)
(signature x0)
(signature x0 x1)
(signature x0 x1 x2)
(signature x0 x1 x2 & xs)
The standard dispatch function for the :hierarchy false
case. Returns the Class
of the argument for arity 1, and an appropriate implementation of Signature
for other arities, calling (.getClass xi)
as needed.
Warning: signature can only be used as a dispatch function with multimethods defined with palisades.lakes.multimethods.core/defmulti.
signature?
added in faster-multimethods 0.0.8
(signature? v)
Is v
a signature (ie, an instance of palisades.lakes.multimethods.java.Signature
)?
to-signature
added in faster-multimethods 0.0.9
(to-signature)
(to-signature c0)
(to-signature c0 c1)
(to-signature c0 c1 c2)
(to-signature c0 c1 c2 & cs)
Return an appropriate instance of Signature
for the Class
valued arguments (in the arity 1 case, it just returns the Class
itself).
Warning: to-signature can only be used to generate dispatch values for multimethods defined with palisades.lakes.multimethods.core/defmulti.