sigildocs

(sigil method)

(sigil method) - Open Dispatch (Multimethods)

Provides define-multi / define-method: Clojure-style multimethods that dispatch over record types, struct types, or core values with one primitive. A base type's method is the inherited default (dispatch walks the type's parent chain), default: registers a catch-all, and methods can be added from any module — solving the expression problem for typed data: a package adds a new type plus its methods without touching the code that dispatches.

Basic Usage

(import (sigil record) (sigil method))

(define-record buffer (name))
(define-record editor-buffer include: buffer (text))

(define-multi describe)

(define-method describe (b editor-buffer) (list 'editor (buffer-name b)))
(define-method describe (b buffer)        (list 'buffer (buffer-name b)))
(define-method describe (x default:)      (list 'value x))

(describe (editor-buffer name: "*e*"))  ; => (editor *e*)   own method
(describe (buffer name: "*b*"))         ; => (buffer *b*)   base method
(describe 42)                           ; => (value 42)     default

A record subtype WITHOUT its own method inherits the nearest ancestor's method — the parent-chain walk covers records and structs alike.

Dispatch Targets

The TYPE position of define-method accepts:

  • a record or struct CONSTRUCTOR (the descriptor is read from its procedure metadata — works across modules)
  • a record-type or struct-type DESCRIPTOR value
  • a core-type symbol: 'dict 'list 'null 'string 'symbol 'keyword 'number 'boolean 'char 'vector 'bytevector 'procedure
  • the keyword default: — the catch-all method

Custom Dispatch Functions

By default a multi dispatches on (value-type first-arg). Pass dispatch: for data-driven dispatch:

(define-multi handle-event dispatch: (lambda (e) (dict-ref e kind:)))
(define-method handle-event (e 'click) ...)

Dispatch keys are compared with eq?: use symbols, keywords, characters, small integers, or record/struct type descriptors as keys — NOT strings, lists, or freshly computed values (they would never match a registered method). The keyword default: is reserved as the catch-all key even under custom dispatch functions (the same convention as Clojure's :default).

Live Redefinition

Methods can be (re)registered at any time (e.g. at the REPL); each registration invalidates the multi's dispatch caches, so the next call sees the new method immediately.

Performance

Each multi memoizes resolved dispatch (type -> method after the parent-chain walk) and keeps a monomorphic fast path for the last dispatched type, so steady-state dispatch is one value-type + one eq? on hot monomorphic call sites (e.g. a render loop over one buffer type).

Exports

value-typeprocedure

The dispatch type of any value: a struct-type descriptor for struct instances, a record-type descriptor for record instances, or a core-type symbol for everything else.

(value-type (person name: "A")) ; => #<struct-type person>
(value-type #{})                ; => dict
(value-type "hi")               ; => string
type-parentprocedure

The parent of a dispatch type: struct/record descriptors walk their inheritance chain; core-type symbols have no parent.

type-nameprocedure

A readable name for a dispatch type (for error messages).

make-multiprocedure

Create a multimethod. Keyword options:

  • dispatch: — a function of the call's arguments producing the dispatch key (default: (value-type first-arg))
  • default: — a fallback handler when no method matches (an alternative to registering a default: method)
(define describe (make-multi))
(multi-add-method! describe buffer (lambda (b) ...))
multi?procedure

Test if a value is a multimethod.

Register a method on a multimethod. TYPE follows the define-method conventions (constructor, descriptor, core-type symbol, or default:). Re-registering a type replaces its method and invalidates the multi's dispatch caches.

multi-methodsprocedure

The multi's registered (dispatch-key . handler) alist — a fresh snapshot for introspection and tooling (mutating it does not affect dispatch; register through multi-add-method!).

define-multivariable

(No description)

(No description)