Skip to main content

mapdispatch

A minimalist library to bring Clojure-style multimethods, method combinations, and tag-based polymorphism into Python — without using classes.

Features

  • Single and multiple argument dispatch
  • Hierarchical dispatch using derive and isa
  • Extensible method registration with defmethod
  • Compositional hooks with :before, :after, and :around
  • Class-free, functional programming style

Installation

Just clone or copy the mapdispatch/ folder into your project.

# if you still use `pip`:
pip install mapdispatch

# but we highly recommend to use `uv`:
uv add mapdispatch

# and after installation via uv you can run the examples by:
mapdispatch-zoo


Quickstart

Define animals as dictionaries

simba = {"name": "Simba", "type": "lion"}
dumbo = {"name": "Dumbo", "type": "elephant"}

Create a hierarchy

from mapdispatch import Hierarchy, MultiMethod

h = Hierarchy()
h.derive("lion", "big-cat")
h.derive("big-cat", "animal")
h.derive("elephant", "animal")

Define a multimethod

feed = MultiMethod(lambda a: a["type"], hierarchy=h)

Register methods

def lion_feed(a):
    print(f"{a['name']} eats meat")

def elephant_feed(a):
    print(f"{a['name']} eats bananas")

feed.defmethod("lion", lion_feed)
feed.defmethod("elephant", elephant_feed)

Use it

feed(simba)   # Simba eats meat
feed(dumbo)   # Dumbo eats bananas

Real Multiple Dispatch

You can dispatch on multiple arguments by making the dispatch function return a tuple:

interact = MultiMethod(lambda a, b: (a["type"], b["type"]), hierarchy=h)

def lion_vs_elephant(a, b):
    print(f"{a['name']} chases {b['name']}")

interact.defmethod(("lion", "elephant"), lion_vs_elephant)

interact(simba, dumbo)  # Simba chases Dumbo

Method Combinations

:before – run logic before the main method

def open_cage(a):
    print(f"Opening cage for {a['name']}")

feed.defmethod("lion", open_cage, kind=":before")

:after – run logic after the main method

def cleanup(a):
    print(f"Cleaning up after {a['name']}")

feed.defmethod("lion", cleanup, kind=":after")

:around – wrap the primary method

def log_feed(inner_fn, a):
    print(f"[LOG] Start {a['name']}")
    result = inner_fn(a)
    print(f"[LOG] End {a['name']}")
    return result

feed.defmethod("lion", log_feed, kind=":around")

Method Registration via Decorators

You can also define methods using decorators instead of manual registration.

Primary method:

@feed.defmethod("lion")
def lion_feed(a):
    print(f"{a['name']} eats meat")

With hooks:

@feed.defmethod("lion", kind=":before")
def open_cage(a):
    print(f"Opening cage for {a['name']}")

@feed.defmethod("lion", kind=":after")
def cleanup(a):
    print(f"Cleaning cage after {a['name']}")

@feed.defmethod("lion", kind=":around")
def logger(inner_fn, a):
    print("[LOG] Start")
    result = inner_fn(a)
    print("[LOG] End")
    return result

this is fully equivalent to manually registering via feed.defmethod(...) and is great for organizeing logic clearly and idiomatically.


Why mapdispatch?

This library helps you:

  • Write open, extensible, polymorphic code
  • Avoid deep class hierarchies
  • Dispatch based on dynamic rules
  • Cleanly separate data from behavior

Inspired by:


Example Output

Opening cage for Simba
[LOG] Start Simba
Simba eats meat
[LOG] End Simba
Cleaning up after Simba

Coming Soon

  • Decorator-based syntax (@defmethod)
  • Predicate-based dispatch
  • Package on PyPI
  • Integration with dataclasses or Pydantic (optional)

Philosophy

“Data is just data. Behavior is just behavior. Dispatch is glue.”
– Not Rich Hickey, but close enough.


Metadata

Release files for mapdispatch 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mapdispatch 0.1.1
File Size Uploaded Provenance Actions
mapdispatch-0.1.1.tar.gz 6.1 kB Without provenance Details for mapdispatch-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mapdispatch 0.1.1
File Interpreter ABI Platform Actions
mapdispatch-0.1.1-py3-none-any.whl Python 3 none any Details for mapdispatch-0.1.1-py3-none-any.whl

Total release size: 12.5 kB

Release files / mapdispatch-0.1.1.tar.gz

Download URL mapdispatch-0.1.1.tar.gz
Size 6.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3e1bd92c680e6b7ead5e7a9c71bd871dcc01c8d9c7fab6774ce48ba1ad213dde
BLAKE2b-256 checksum
How to use checksums
02b75cec1ebaf05b025c3ef8f597c7ca1e64a83fbfde6758015fb8490e395dc1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.4

Release files / mapdispatch-0.1.1-py3-none-any.whl

Download URL mapdispatch-0.1.1-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af8a30238dd0993b00b5409ec499022722ef4811be7a7054c5651350d5f2bb79
BLAKE2b-256 checksum
How to use checksums
aee9fcb5ef521a91cfa67222ae16b8a8da62ef7c9d1e2f7f0dc77e251c4eed01
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.4

Security for mapdispatch 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page