Choreographies are a way of describing communicating systems as global programs

A

🕺🏽

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

B

🕺

```
x = receive("A")
y = crunch(x)
```

A

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

B

```
x = receive("a")
y = crunch(x)
send("A",y)
```

A

```
x = crunch()
send("B",x)
y = receive("B")
```

B

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

A

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

B

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

A

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

B

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

A

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

B

```
x = receive("A")
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

```
x = receive("A")
y = crunch(x)
```

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

A

```
x = crunch()
send("B",x)
y = receive("B")
```

B

```
x = receive("A")
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)
y = receive("B")
```

B

```
x = receive("A")
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:
z = receive("A")
...
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:
z = receive("A")
...
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> -> B; G` | (sel) | |

`|` |
`Let x@A = foo(..); G` | (let) | |

`|` |
```
If x@A
Then G
Else G
``` | (if) | |

`|` |
`End` | (end) |

Semantics

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()
x = receive("A")
```

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

A

```
x = crunch()
send("B",x)
y = receive("B")
```

B

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

Confluence

Deadlock-freedom

$\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` | `::=` |
`<p,s,q,EP>` | (Single) |

`|` |
`<p,s,q,EP> || 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,>`

```
Receive "A" x
...
```

`<A,sa,qa,>`

```
...
```

`sa(x) = d`

`<B,sb,qb',>`

```
Receive "A" x
...
```

`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~~

Payload

```
IntChoice b p
...
```

```
Let fv = b
Send p fv
...
```

```
ExternalChoice p e1 e2
```

```
Receive p fv
If fv Then e1 Else e2
```

```
Send p vlm
...
```

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

```
Receive p vlm
...
```

```
Receive p v
Receive p l
Receive p m
...
```

EPN

~~Selection~~

Payload

- Instruments CakeML with
`send`

and`receive`

ffi calls - All programs are deadlock-free when executed along with the other endpoints