## What is a choreography?

Choreographies are a way of describing communicating systems as global programs

A

🕺🏽

x = crunch()
send("B",x)


B

🕺

y = crunch(x)


A


x = crunch()
send("B",x)


B


y = crunch(x)
send("A",y)


A


x = crunch()
send("B",x)


B


y = crunch(x)
send("A",y)


A


x = crunch()
send("B",x)
if y > 100:
z = crunch(y)
send("B",z)
else:
exit 1


B


y = crunch(x)
send("A",y)


A


x = crunch()
send("B",x)
if y > 100:
z = crunch(y)
send("B",z)
else:
exit 1


B


y = crunch(x)
send("A",y)
if y > 100:
...
else:
exit 1


A


x = crunch()
send("B",x)
z = crunch(y)
if z > 100:
send("B",z)
else:
exit 1


B


y = crunch(x)
send("A",y)


## ?


let x@A = crunch()
A[x] -> B.x
let y@B = crunch(x)


A


x = crunch()
send("B",x)


B


y = crunch(x)


let x@A = crunch()
A[x] -> B.x
let y@B = crunch(x)


A


x = crunch()
send("B",x)


B


y = crunch(x)
send("A",y)


let x@A = crunch()
A[x] -> B.x
let y@B = crunch(x)
B[y] -> A.y


A


x = crunch()
send("B",x)


B


y = crunch(x)
send("A",y)


let x@A = crunch()
A[x] -> B.x
let y@B = crunch(x)
B[y] -> A.y


A


...
if y > 100:
z = crunch(y)
send("B",z)
else:
exit 1


B


...
if y > 100:
...
else:
exit 1


//...
let v@A = y > 100
if v@A {
A<T> -> B
let z@A = crunch(y)
A.[z] -> B.z
//...
} else {
A<F> -> B
//DONE
}


A


...
if y > 100:
z = crunch(y)
send("B",z)
else:
exit 1


B


...
if y > 100:
...
else:
exit 1

🕺🕺🏽

//...
let v@A = y > 100
if v@A {
A<T> -> B
let z@A = crunch(y)
A.[z] -> B.z
//...
} else {
A<F> -> B
//DONE
}


Syntax

 G ::= A[x] -> B.y; G (com) | A -> B; G (sel) | Let x@A = foo(..); G (let) | If x@A Then G Else G (if) | End (end)

Semantics

### $(s,c) \xrightarrow{(\tau,l)} (s',c')$

Where:

• $c$ and $c'$ are choreographies
• $s$ and $s'$ are mappings from pairs of process and variables to values

Communication

A[x] -> B.y;C

Communication

S
A[x] -> B.y;C

Communication

S(A,x) = d
 A[x] -> B.y;C

Communication

 A[x] -> B.y;C 
S[(B,y)|->d]

Communication

S[(B,y)|->d]
C

Features

Concurrency

Concurrency


A[x] -> B.y
P[z] -> Q.w
✅


A[x] -> B.y
P[z] -> Q.w
C[m] -> D.k


A[x] -> B.y
✅
C[m] -> D.k


✅
P[z] -> Q.w
C[m] -> D.k


Asyncrony

Asyncrony


A[x] -> B.y
P[z] -> A.w
A[m] -> D.k


Asyncrony


A[x] -> B.y
P[z] -> A.w
A[m] -> D.k


✅
P[z] -> A.w
A[m] -> D.k


Asyncrony


A[x] -> B.y
P[z] -> A.w
A[m] -> D.k


✅ -> B.y
P[z] -> A.w
A[m] -> D.k


✅ -> ✅
P[z] -> A.w
A[m] -> D.k


Asyncrony


A[x] -> B.y
P[z] -> A.w
A[m] -> D.k


✅ -> B.y
✅
A[m] -> D.k


✅
P[z] -> A.w
A[m] -> D.k


Asyncrony


A[x] -> B.y
P[z] -> A.w
❌


A[x] -> B.y
P[z] -> A.w
A[m] -> D.k


A[x] -> B.y
✅
A[m] -> D.k


✅
P[z] -> A.w
A[m] -> D.k


Projection


let x@A = crunch()
let y@B = crunch()
A[x] -> B.x
B[y] -> A.y


let x@A = crunch()
let y@B = crunch()
A[x] -> B.x
B[y] -> A.y


A


x = crunch()


let x@A = crunch()
let y@B = crunch()
A[x] -> B.x
B[y] -> A.y


A


x = crunch()


B


y = crunch()


let x@A = crunch()
let y@B = crunch()
A[x] -> B.x
B[y] -> A.y


A


x = crunch()
send("A",x)


B


y = crunch()


let x@a = crunch()
let y@b = crunch()
A[x] -> B.x
B[y] -> A.y


A


x = crunch()
send("B",x)


B


y = crunch()
send("A",y)


Confluence $\text{fv}(c) \subseteq \text{fv}(s) \implies \exists{s'.}{(s,c) \rightarrow^{\ast} (s',end)}$

A[x] -> B.x
B[y] -> A.y A[x] -> B.x
B[y] -> A.y A[x] -> B.x
B[y] -> A.y An endpoint language

 EPN ::=  (Single) |  || EPN (Parallel)

Where:

• (p) is a process name
• (s) is a mappings from varible names to values representing the process state,
• (q) is a queue of unread messages
• (EP) is the endpoint code
 EP ::= Send p x; EP | Receive p y; EP | InternalChoice p b; EP | ExternalChoice p EP EP | Let v f vl in EP | If v Then EP Else EP | End

<A,sa,qa,>


Send "B" x
...


sa(x) = d

<B,sb,qb,>


...


<A,sa,qa,>


...


sa(x) = d

<B,sb,qb',>


...


qb' = ("A",d)::qb

<A,sa,qa,>


...


<B,sb',qb,>


...


sb' = sb[x |-> d]

project(p,c) = (succ,EP)

Where:

• (p) is a process name
• (c) is a choreography
• (EP) is a single endpoint
• (succ) is a boolean signaling success

Definition project_def:
...
∧ project proc (Com p1 v1 p2 v2 c) =
if proc = p1 ∧ proc = p2
then (F,Nil)
else if proc = p1
then Send p2 v1 <Γ> project proc c
else if proc = p2
then Receive p1 v2 <Γ> project proc c
else project proc c
...


Semantic preservation

 $(s,c)\xrightarrow{}(s',c')$ $\exists{c'',s''.\;}(s',c')\rightarrow^{\ast}(s'',c'')\,\land\, [\![s,c]\!]\rightarrow^{\ast}[\![s'',c'']\!]$

Semantic reflection

 $[\![s,c]\!]\xrightarrow{}epn$ $\exists{c',s'.\;}epn\rightarrow^{\ast}[\![s',c']\!]\,\land\, (s,c)\rightarrow^{\ast}(s',c')$

EPN EPN

Selection IntChoice b p
...


Let fv = b
Send p fv
...


ExternalChoice p e1 e2


If fv Then e1 Else e2


Send p vlm
...


Send p v
Send p l
Send p m
...


...


...

*Wildly oversimplified

EPN

Selection       • Instruments CakeML with send and receive ffi calls 