Examples tour¶
Every example below is a real, runnable @choreography (most come straight
from examples.py / the test suite).
Ping-pong¶
One-way send; the result lives at B.
@choreography
def ping_pong(x):
y = move(x, A, B)
return y
simulate_chor(ping_pong, {"x": 42})
# {'A': NOOP, 'B': 42}
Relay¶
A three-role chain: A → B → C.
Knowledge of choice¶
Only A sees the parity test; B only learns x on the even path — and
computes its own fallback on the odd path.
@choreography
def verdict(x):
is_even = A(x % 2 == 0)
if is_even:
r = move(x, A, B)
return r
else:
r = B(abs(x))
return r
Remote call¶
A ships x to B, B runs f locally, the result comes home.
@choreography
def remote_call(f, x): # f, x are agreement values
sent = move(x, A, B)
computed = B(f(sent))
result = move(computed, B, A)
return result
simulate_chor(remote_call, {"f": lambda n: n * n, "x": 9})
# {'A': 81, 'B': NOOP}
Distributed sum, per-role parameters¶
Each role only ever receives its own operand.
@choreography
def dist_sum(x: A, y: B) -> A:
sx = move(x, A, B)
total = B(sx + y)
total2 = move(total, B, A)
return total2
simulate_chor(dist_sum, {"x": 5, "y": 7})
# {'A': 12, 'B': NOOP}
Lockstep loop with communication¶
A token circles the ring, and B/C each add 1 per round.
@choreography
def ring_rounds(rounds, init) -> A:
acc = A(init)
i = 0
while i < rounds:
i = i + 1
m1 = move(acc, A, B)
bval = B(m1 + 1)
m2 = move(bval, B, C)
cval = C(m2 + 1)
acc = move(cval, C, A)
return acc
simulate_chor(ring_rounds, {"rounds": 3, "init": 10})
# {'A': 16, ...} # 10 + 3 × 2
Broadcast loop (subset-decided condition)¶
The counter lives at A; A decides each pass and keeps B in step while B
adds to the value.
@choreography
def relay_until(n) -> A:
c = A(n)
result = A(0)
while c > 0:
b = move(result, A, B)
bb = B(b + 1)
result = move(bb, B, A)
c2 = A(c - 1)
c = c2
return result
simulate_chor(relay_until, {"n": 4})
# {'A': 4, 'B': NOOP}
Where these live¶
Run them all with: