Dynamic multiple dispatch
(require multimethod) | package: multimethod-lib |
This library provides syntactic forms for defining and implementing multimethods, dynamically polymorphic functions that support multiple dispatch. Multimethods are functions that can have many different implementations depending on the types of arguments they are invoked on. For example, a generic add function might have different implementations for adding scalars and vectors.
Multimethods provide similar but distinct functionality from racket/generic, which permits enhancing implementing structures in more powerful ways, but only supports single dispatch.
1 Example
; a scalar value > (struct num (val)) ; an n-dimensional vector value > (struct vec (vals)) ; generic multiplication operator > (define-generic (mul a b))
> (define-instance ((mul num num) x y) (num (* (num-val x) (num-val y))))
> (define-instance ((mul num vec) n v) (vec (map (curry * (num-val n)) (vec-vals v))))
> (define-instance ((mul vec num) v n) (mul n v)) > (mul (num 6) (num 8)) (num 48)
> (mul (num 2) (vec '(3 12))) (vec '(6 24))
> (mul (vec '(3 12)) (num 2)) (vec '(6 24))
2 API Reference
syntax
(define-generic (name-id param-or-hole ...+))
param-or-hole = param-id | _
syntax
(define-instance (name-id type-id ...+) proc-expr)
(define-instance ((name-id type-id ...+) formal-id ...+) body ...+)
When using the first form of define-instance, proc-expr should produce a procedure that will be invoked when an invokation of the multimethod matches the provided types. The second form is analogous to the usual function definition shorthand, such as the second form of define.
New multimethod instances cannot be defined on any combination of datatypes—there are rules that govern which instances are valid. Specifically, a multimethod instance is only valid if either of the following conditions are met:
The multimethod bound by name-id was defined in the same module as the instance definition.
Any of the types bound by the type-ids were defined in the same module as the instance definition.
These requirements guarantee that there cannot be two conflicting instances defined in separate modules, which would cause problems when both loaded at the same time.
syntax
(struct id fields options)