Dynamic multiple dispatch
1 Example
2 API Reference

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


(define-generic (name-id param-or-hole ...+))

param-or-hole = param-id
  | _
Defines a new multimethod with the name name-id. Each param-or-hole corresponds to a formal parameter to the function. Each argument given a name will be considered for dispatch, but arguments may be simply passed through by replacing them with _.


(define-instance (name-id type-id ...+) proc-expr)

(define-instance ((name-id type-id ...+) formal-id ...+) body ...+)
Defines a new instance of the multimethod bound by name-id for the combination of types provided, where each type-id refers to a structure type transformer binding.

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:

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.


(struct id fields options)

Like struct from racket/base, but wrapped to cooperate with the instance validity checking of define-instance. Additionally, all structs defined with this form are #:transparent. Otherwise identical to struct.