The RPC Calculus Symmetrical RPC in an Asymmetrical World Ezra - - PowerPoint PPT Presentation

the rpc calculus
SMART_READER_LITE
LIVE PREVIEW

The RPC Calculus Symmetrical RPC in an Asymmetrical World Ezra - - PowerPoint PPT Presentation

The RPC Calculus Symmetrical RPC in an Asymmetrical World Ezra Cooper Philip Wadler September 8, 2009 Dream of unified web programming Dream of unified web programming What we want Reality of web programming Reality of web programming


slide-1
SLIDE 1

The RPC Calculus

Symmetrical RPC in an Asymmetrical World Ezra Cooper Philip Wadler September 8, 2009

slide-2
SLIDE 2

Dream of unified web programming

slide-3
SLIDE 3

Dream of unified web programming What we want

slide-4
SLIDE 4

Reality of web programming

slide-5
SLIDE 5

Reality of web programming It’s a bit more fiddly.

slide-6
SLIDE 6

Reality of web programming It’s a bit more fiddly. Here’s why:

slide-7
SLIDE 7

Traditional program

slide-8
SLIDE 8

Traditional program

slide-9
SLIDE 9

Traditional web program .

slide-10
SLIDE 10

Traditional web program .

slide-11
SLIDE 11

Unified program

slide-12
SLIDE 12

Unified program Simplifies the work of web programming

slide-13
SLIDE 13

Unified program Simplifies the work of web programming The Links language: http://groups.inf.ed.ac.uk/links

slide-14
SLIDE 14

Dream of a unified language

Waking up:

◮ Desire to control location explicitly, with a light touch; ◮ Need control for performance and security reasons; ◮ Tricky because of asymmetrical client/server relationship.

slide-15
SLIDE 15

Roadblock: Asymmetrical client/server relationship

slide-16
SLIDE 16

Roadblock: Asymmetrical client/server relationship

slide-17
SLIDE 17

Stateless server

Web applications should not store control state at the server.

slide-18
SLIDE 18

Stateless server

Web applications should not store control state at the server. Server should encode all state and give it to client.

slide-19
SLIDE 19

Stateless server

Web applications should not store control state at the server. Server should encode all state and give it to client. For this talk, state = call stack.

slide-20
SLIDE 20

Example program

fun checkPassword(name, password) { # load this user’s row from database & check password var u = lookupUser(name); u.password == password } fun validate() { var auth = checkPassword(fieldValue(”name”), fieldValue(”password”))); if (auth) displaySecretDocument(); else displayErrorMessage(); }

slide-21
SLIDE 21

Example located program

fun checkPassword(name, password) server { # load this user’s row from database & check password var u = lookupUser(name); u.password == password } fun validate() client { var auth = checkPassword(fieldValue(”name”), fieldValue(”password”))); if (auth) displaySecretDocument(); else displayErrorMessage(); }

slide-22
SLIDE 22

Example located program: server push

fun findFlights(flightQuery) server { # Query each vendor for its own matching flights for (vendor ← airlines()) { var flights = queryVendor(vendor, flightQuery); # Send this vendor’s flights to the browser displayFlights(flights); } } fun displayFlights(flights) client { # Add each flight to the page for (flight ← flights) addToPage(flight); }

slide-23
SLIDE 23

Example: higher-order functions

How should this code behave? fun usernameMap(f ) server { var users = getUsersFromDatabase(); for (u ← users)[f (u.name)] } fun userNameFirstThree() client { usersMap(fun(name){take(3, name)}); }

slide-24
SLIDE 24

Example: higher-order functions

How should this code behave? fun usernameMap(f ) server { var users = getUsersFromDatabase(); for (u ← users)[f (u.name)] } fun userNameFirstThree() client { usersMap(fun(name){take(3, name)}); }

⊲ Functions in lexical client-context execute on client.

slide-25
SLIDE 25

What I want to show you

◮ How to compile this language for the asymmetrical

client-server model,

slide-26
SLIDE 26

What I want to show you

◮ How to compile this language for the asymmetrical

client-server model,

◮ How the compilation factors into standard techniques,

slide-27
SLIDE 27

What I want to show you

◮ How to compile this language for the asymmetrical

client-server model,

◮ How the compilation factors into standard techniques, ◮ How these these techniques can be presented formally and

concisely.

slide-28
SLIDE 28

How it’s done

Call to f (server) Call to g (client) Return r from g Return s from f {Call f} {Call g, k} {Continue r, k} {Return s} main Client Server

Source language: call/return style Implementation: request/response style

f g

slide-29
SLIDE 29

Getting technical

slide-30
SLIDE 30

Source language: the located lambda calculus

slide-31
SLIDE 31

Source language: the located lambda calculus

L, M, N ::= LM | λax.N | λx.N | x | c a, b ::= c | s

slide-32
SLIDE 32

Source language: the located lambda calculus

L, M, N ::= LM | λax.N | λx.N | x | c a, b ::= c | s We eliminate un-located forms λx.N by explicitly copying the location of their lexical context. So λcx.L(λy.N) becomes λcx.L(λcy.N)

slide-33
SLIDE 33

Source language: the located lambda calculus

L, M, N ::= LM | λax.N | x | c a, b ::= c | s We eliminate un-located forms λx.N by explicitly copying the location of their lexical context. So λax.L(λy.N) becomes λcx.L(λcy.N)

slide-34
SLIDE 34

Semantics

Read M ⇓a V as ”M evaluates, starting at a, to V .” V ⇓a V (Value) L ⇓a λbx.N M ⇓a W N{W /x} ⇓b V LM ⇓a V (Beta) L ⇓a c M ⇓a W δa(c, W ) ⇓a V LM ⇓a V (Delta)

slide-35
SLIDE 35

Translation to a client-server system

Three techniques:

◮ CPS translation:

reifies the control state

◮ Defunctionalization:

turns higher-order functions into data (serializable)

◮ Trampolining:

inverts control, so state resides at client.

slide-36
SLIDE 36

CPS translation (due to Fischer, 1972, via Sabry and Wadler, 1997)

Source: L, M, N ::= LM | V V ::= λx.N | x CPS translation: (LM)†K = L†(λf .M†(λx.fxK)) V †K = KV ◦ (λx.N)◦ = λx.λk.N†k x◦ = x

slide-37
SLIDE 37

Defunctionalization

slide-38
SLIDE 38

Defunctionalization target

D ::= letrec D and · · · and D D ::= f ( x) = case x of A A ::= a set of A items A ::= F( c) ⇒ M M ::= f ( M) | F( M) | x | c

slide-39
SLIDE 39

Defunctionalization target

D ::= letrec D and · · · and D D ::= f ( x) = case x of A A ::= a set of A items A ::= F( c) ⇒ M M ::= f ( M) | F( M) | x | c function names f , g constructor names F, G

slide-40
SLIDE 40

Defunctionalization (orig. Reynolds, 1972)

[ [M] ]top = letrec apply(fun, arg) = case fun of [ [M] ]fun∗ in [ [M] ] [ [λx.N] ]fun = λx.N( y) ⇒ [ [N] ]{arg/x} where y = fv(λx.N) [ [LM] ] = apply([ [L] ], [ [M] ]) [ [V ] ] = V ◦ (λx.N)◦ = λx.N( y) where y = fv(λx.N) x◦ = x The operation M gives an opaque identifier for the term M.

slide-41
SLIDE 41

Trampolining (due to Ganz, Friedman and Wand)

◮ Continually returns control to a top-level trampoline; ◮ Works on any tail-form program,

including CPS programs;

◮ Choice of the trampoline modifies the behavior.

slide-42
SLIDE 42

Trampolining

(LM)T = Bounce(λz.LtMt) (where z is a dummy) V T = Return(V t) (λx.N)t = λx.NT xt = x Behavior depends on our choice of tramp.

slide-43
SLIDE 43

Example trampolines

Trivial trampoline: tramp(x) = case x of Bounce(thunk) ⇒ tramp(thunk()) | Return(x) ⇒ x

slide-44
SLIDE 44

Example trampolines

Trivial trampoline: tramp(x) = case x of Bounce(thunk) ⇒ tramp(thunk()) | Return(x) ⇒ x Step-counting trampoline: tramp(n, x) = case x of Bounce(thunk) ⇒ print(n); tramp(n + 1, thunk()) | Return(x) ⇒ x

slide-45
SLIDE 45

Our trampoline

Since the control state is reified, tramp can split the computation into a client- and a server-side piece. tramp(x) = case x of | Bounce(f , x, k) ⇒ tramp(req cont (k, apply(f , x))) | Return(x) ⇒ x (This shouldn’t make sense yet; don’t worry.)

slide-46
SLIDE 46

Our trampoline

Since the control state is reified, tramp can split the computation into a client and a server-side piece. tramp(x) = case x of | Call(f , x, k) ⇒ tramp(req cont (k, apply(f , x))) | Return(x) ⇒ x (This shouldn’t make sense yet; don’t worry.)

slide-47
SLIDE 47

The Big Transformation

slide-48
SLIDE 48

First, the target: first-order client-server calculus

slide-49
SLIDE 49

The client-server calculus

Syntax configurations K ::= (M; ·) | (E; M) terms L, M, N ::= x | c | F( M) | f ( M) | req f ( M) definition set D, C, S ::= letrec D and · · · and D function definitions D ::= f ( x) = case M of A alternative sets A a set of A items case alternatives A ::= F( x) ⇒ M function names f , g constructor names F, G

slide-50
SLIDE 50

Configurations of the machine

slide-51
SLIDE 51

Semantics

Client: (E[f ( V )]; ·) − →C,S (E[M{ V / x}]; ·) if (f ( x) = M) ∈ C (E[case (F( V )) of A]; ·) − →C,S (E[M{ V / x}]; ·) if (F( x) ⇒ M) ∈ A Server: (E; E ′[f ( V )]) − →C,S (E; E ′[M{ V / x}]) if (f ( x) = M) ∈ S (E; E ′[case (F( V )) of A]) − →C,S (E; E ′[M{ V / x}]) if (F( x) ⇒ M) ∈ A Communication: (E[req f ( V )]; ·) − →C,S (E; f ( V )) (E; V ) − →C,S (E[V ]; ·)

slide-52
SLIDE 52

Now, the translation

slide-53
SLIDE 53

Transformation on terms

(λax.N)◦ = λax.N( y)

  • y = fv(λax.N)

x◦ = x c◦ = c V ∗ = V ◦ (LM)∗ = apply(L∗, M∗) V †[ ] = cont([ ], V ◦) (LM)†[ ] = L†(M( y, [ ])) where y = fv(M)

slide-54
SLIDE 54

Transformation to definitions (client-side)

[ [M] ]c,top = letrec apply(fun, arg) = case fun of [ [M] ]c,fun and tramp(x) = case x of | Call(f , x, k) ⇒ tramp(req cont (k, apply(f , x))) | Return(x) ⇒ x [ [λcx.N] ]c,fun = λcx.N( y) ⇒ N∗{arg/x} where y = fv(λx.N) [ [λsx.N] ]c,fun = λsx.N( y) ⇒ tramp(req apply (λsx.N( y), arg, Fin())) where y = fv(λx.N)

slide-55
SLIDE 55

Transformation to definitions (server-side)

[ [M] ]s,top = letrec apply(fun, arg, k) = case fun of [ [M] ]s,fun and cont(k, arg) = case k of [ [M] ]s,cont | App(fun, k) ⇒ apply(fun, arg, k) | Fin() ⇒ Return(arg) [ [λsx.N] ]s,fun = λsx.N( y) ⇒ (N†k){arg/x} where y = fv(λx.N) [ [λcx.N] ]s,fun = λcx.N( y) ⇒ Call(λcx.N( y), arg, k) where y = fv(λx.N) [ [LM] ]s,cont = M( y, k) ⇒ M†(App(arg, k)) where y = fv(M)

slide-56
SLIDE 56

Correctness: Bisimulation

M ⇓

✲ V

M′ − ։ ✲ V ′ M ⇓

✲ V

M′ − ։ ✲ V ′

slide-57
SLIDE 57

Summary

We can

slide-58
SLIDE 58

Summary

We can

◮ Enrich a functional programming language with location

annotations,

slide-59
SLIDE 59

Summary

We can

◮ Enrich a functional programming language with location

annotations,

◮ which designate execution location of their contents lexically,

slide-60
SLIDE 60

Summary

We can

◮ Enrich a functional programming language with location

annotations,

◮ which designate execution location of their contents lexically, ◮ and whose semantics are straightforward,

slide-61
SLIDE 61

Summary

We can

◮ Enrich a functional programming language with location

annotations,

◮ which designate execution location of their contents lexically, ◮ and whose semantics are straightforward, ◮ and we can execute these programs on an asymmetrical

client-server system with a “stateless server”

slide-62
SLIDE 62

Summary

We can

◮ Enrich a functional programming language with location

annotations,

◮ which designate execution location of their contents lexically, ◮ and whose semantics are straightforward, ◮ and we can execute these programs on an asymmetrical

client-server system with a “stateless server”

◮ using a combination of classic transformations.

slide-63
SLIDE 63

Summary

We can

◮ Enrich a functional programming language with location

annotations,

◮ which designate execution location of their contents lexically, ◮ and whose semantics are straightforward, ◮ and we can execute these programs on an asymmetrical

client-server system with a “stateless server”

◮ using a combination of classic transformations.

Thank you