Skip to content

Operators

The DSL is a small, deliberately constrained subset of Python. Every construct is validated at definition time; unsupported ones raise a clear error instead of miscompiling.

Lifting: A(x) and lift

A(x) (or lift(x, A) / lift(x, {A, B})) lifts an expression to a role: it says "this value is produced at A". Only A evaluates the expression; the result is located at {A} (or the given role set).

is_even = A(x % 2 == 0)     # only A computes this; located at {A}

Communication: copy, narrow, move

Operator Effect Result location
copy(x, A, B) communicate x from A to B loc(x) ∪ {B}
narrow(x, {A}) forget other locations (no communication) {A}
move(x, A, B) shorthand: narrow(copy(x, A, B), {B}) {B}

copy requires A ∈ loc(x); narrow requires the target set to be a subset of loc(x). These are checked statically, per role, at definition time:

y = move(x, A, B)   # x must be located at A; rejected otherwise

Communication operands are variables

copy/move/narrow operands must already be choreographic variables (names). Write the expression first, then move it:

b = B(x + 1)
y = move(b, B, A)

Tuple values: pack and unpack

pack(a, b, …) groups located values into a tuple value; unpack([x, y], t) pulls one apart, binding each element at its own location.

t = pack(x, y)   # element 0 located where x is, element 1 where y is
unpack([a, b], t)   # a @ loc(x), b @ loc(y)

Each role materializes a zone-filled view of a tuple — real values for the elements it holds, UNHELD elsewhere — so tuples need no communication to build or read. See Types & parameters.

Communication stays scalar

copy/move/narrow/lift take scalar (agreement) operands only. Moving a distributed tuple is not supported: unpack it, move the parts, and repack. (Each element already lives at its role, so this is rarely needed.)

Role actions: Role.print

A.print(x) prints x at role A (useful while simulating).

What's not here (yet)

There is no agree! (programmer-declared agreement — the unsafe escape hatch Klor has), no defchor forward-declaration/mutual recursion, and no higher-order choreography-as-value types. These are documented in Limitations.