Skip to content

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.

@choreography
def relay(x):
    m1 = move(x, A, B)
    m2 = move(m1, B, C)
    return m2

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:

$ python examples.py         # the one-process showcase
$ python -m pytest tests/    # 47 tests, including TCP
$ python examples_network.py # two OS processes over real TCP