Relationship to Klor¶
KlorPy is a Python port of the ideas behind Klor: Choreographies in Clojure, by Lovro Lugović and Sung-Shik Jongmans (Heart of Clojure 2024, funded by NGI Assure/NLnet).
Shared ideas¶
The conceptual core is the same:
| Idea | Klor (Clojure) | KlorPy (Python) |
|---|---|---|
| Choreographic programming | an EDSL: write one global program, project to per-role programs | the same, via @choreography |
| Location type system | agreement / tuple / chor types | _UNIVERSAL / frozenset / tuple |
| Special operators | lifting, copy, narrow, move, pack, unpack, agree! |
lift, copy, narrow, move, pack, unpack |
| Knowledge of choice | a role appears in a branch only if it is part of the guard's agreement | universal guards decide locally; subset guards broadcast |
| Erasure | play-role takes only the parameters that mention a role |
Choreography.bind_param / role_holds_param |
| Runtime | play-role + role config {role, send, recv, locators}; simulate-chor |
play_role + the same config shape; simulate_chor |
| TCP transport | klor.sockets (java.nio + Nippy) |
klorpy.sockets (asyncio + pickle) |
The simulate_chor/play_role API shape, the role-config transport contract,
the NOOP sentinel, and the location lattice are deliberate mirrors of Klor —
so the mental model transfers directly.
What had to change (no macros in Python)¶
- The compiler front end. Clojure gives Klor reader macros and
tools.analyzer.jvm;defchortype-checks and projects at macroexpansion. Python has neither, so@choreographyparses the function's source (inspect+ast), runs the same analysis/typecheck/projection passes, and compiles per-role async closures instead of per-role source. - Control flow is real Python.
if,match,while,break,continueare the native statements (with amatchextension for case). Klor's functional style (recur) maps to thewhileconstruct here. - The transport is Python's async ecosystem.
asynciogives us the simulator (one task per role + in-memory queues) and the TCP transport for free.
Deliberate differences¶
- No
agree!yet and nodefchorforward declarations — documented in the roadmap; both are future conveniences. - More permissive choice. Klor restricts branch participation to the guard's agreement set statically. KlorPy instead broadcasts the decision to any participating role, which is more permissive (and lets the same choreography style handle single-role guards).
- No mypy plugin for the type checker (explained in the roadmap).
- Scope honesty. KlorPy is a documented prototype (~1,100 lines of Python
- 47 tests), not a production system. The limitations page is the contract.
Learning Klor through KlorPy¶
If you want to understand Klor's papers (the book-length treatment of choreographies is the best entry point), KlorPy is a readable, runnable companion: the location model, projection, erasure, and transport all exist in ~1,100 lines of Python with no external dependencies.