Session-ocaml : a Session-based Library with Polarities and Lenses Keigo Imai Nobuko Yoshida Shoji Yuen Gifu University, JP Imperial College London, UK Nagoya University, JP COORDINATION 2017 Neuchâtel, Switzerland 20th June, 2017
Introduction • Implementation of distributed software is notoriously difficult • OCaml: a concise language with fast runtime • Various concurrent/distributed applications − High freq. trading in Jane Street Capital − Ocsigen/Eliom [web server/framework] , BuckleScript [translates to JavaScript] − MirageOS, MLDonkey [P2P] • Aim: to give a static assuarance for communicating software 2
Session-ocaml: A Session Type implementation in OCaml Session types guarantee communication safety and session fidelity in OCaml • Two novel features: • #1. Session-Type (Duality) Inference → Equality-based duality checking by polarised session types #2. Linearity in (non-linear) OCaml types → Statically-typed delegation with slot-oriented programming 3
Session-ocaml in a Nutshell: (1) Session-type inference let main () = send "Hello" >> Session-ocaml program: let%s x = recv () in close () #1: via Session-type inference solely "Polarised session types" (explained later) done by OCaml compiler val main: Type signature req[string];resp[ τ ];close (inferred): (much simplified than reality) 4
Session-ocaml in a Nutshell: (2) Linearity by slot-oriented programming Slot-oriented session programming: GV-style session programming: (in Session-ocaml) (in FuSe [Padovani'16] and GVinHS [Lindley&Morris,'16]) send _0 "Hello" >> let s' = send s "Hello" in let%s x = recv _0 in let x, s'' = recv s' in close s'' close _0 1. A new session endpoint is created for each communication step 2. Every endpoint must be linearly used (not checkable by OCaml types) 5
Session-ocaml in a Nutshell: (2) Linearity by slot-oriented programming Slot-oriented session programming: GV-style session programming: (in Session-ocaml) (in FuSe [Padovani'16] and GVinHS [Lindley&Morris,'16]) a few use monads syntactic extensions send _0 "Hello" >> let s' = send s "Hello" in let%s x = recv _0 in let x, s'' = recv s' in close s'' close _0 1. A new session endpoint is created for each communication step 2. Every endpoint must be linearly used (not checkable by OCaml types) 5
Session-ocaml in a Nutshell: (2) Linearity by slot-oriented programming Slot-oriented session programming: GV-style session programming: (in Session-ocaml) (in FuSe [Padovani'16] and GVinHS [Lindley&Morris,'16]) a few use monads syntactic extensions send _0 "Hello" >> let s' = send s "Hello" in let%s x = recv _0 in let x, s'' = recv s' in close s'' close _0 Use "slot" numbers ( _0 , _1 ,..) as place-holders 1. A new session endpoint is created for #2: Provides linearity on top of each communication step 2. Every endpoint must be linearly used NON-linear type system (not checkable by OCaml types) 5
History of Session type implementation (in Haskell & OCaml) Neubauer & Thiemann '06 Pucella & Tov, '08 Pucella & Tov, '08 Haskell Sackman & Eisenbach, '08 Imai, Yuen & Agusa, '10 Orchard & Yoshida , '16 OCaml Lindley & Morris, '16 Padovani, '16 Imai, Yoshida & Yuen, '17 Very few OCaml-based session types -- Duality and Linearity were the major obstacles (which Haskell coped with various type-level features) 6
History of Session type implementation (in Haskell & OCaml) Neubauer & Thiemann '06 Pucella & Tov, '08 Pucella & Tov, '08 Haskell Sackman & Eisenbach, '08 Imai, Yuen & Agusa, '10 Orchard & Yoshida , '16 FuSe OCaml Lindley & Morris, '16 Padovani, '16 Imai, Yoshida & Yuen, '17 Session-ocaml Very few OCaml-based session types -- Duality and Linearity were the major obstacles (which Haskell coped with various type-level features) 6
Presentation structure Introduction Feature #2: Mimicked Linearity Feature #1: L2: ownership L1: state transition Polarised Session Types Slot monads and Lenses Parameterised monad Session-ocaml Discussion Summary 7
Original session types and polarised session types Original session types [Honda '97]: Polarised session types: !int;close req[int];close cli ?string;!bool;close resp[string];req[bool];close cli μα .!ping;?pong; α μα .resp[ping];req[pong]; α serv Duality: Duality: ! v ; S =? v ; S & { l i : S i } = ⊕ { l i : S i } ? v ; S =! v ; S ⊕ { l i : S i } = & { l i : S i } P serv = P cli P cli = P serv µ α .S = µ α .S [ α / α ] close = close Duality is too complex to have in OCaml type 8
Original session types and polarised session types Original session types [Honda '97]: Polarised session types: !int;close req[int];close cli ?string;!bool;close resp[string];req[bool];close cli μα .!ping;?pong; α μα .resp[ping];req[pong]; α serv Use { req , resp } instead of { ! , ? } Duality: Duality: ! v ; S =? v ; S & { l i : S i } = ⊕ { l i : S i } ? v ; S =! v ; S ⊕ { l i : S i } = & { l i : S i } P serv = P cli P cli = P serv µ α .S = µ α .S [ α / α ] close = close Duality is too complex to have in OCaml type 8
Original session types and polarised session types Original session types [Honda '97]: Polarised session types: Polarity { cli , serv } gives !int;close req[int];close cli modality ?string;!bool;close resp[string];req[bool];close cli μα .!ping;?pong; α μα .resp[ping];req[pong]; α serv Use { req , resp } instead of { ! , ? } Duality: Duality: ! v ; S =? v ; S & { l i : S i } = ⊕ { l i : S i } ? v ; S =! v ; S ⊕ { l i : S i } = & { l i : S i } P serv = P cli P cli = P serv µ α .S = µ α .S [ α / α ] close = close Duality is too complex to have in OCaml type 8
Original session types and polarised session types Original session types [Honda '97]: Polarised session types: Polarity { cli , serv } gives !int;close req[int];close cli modality ?string;!bool;close resp[string];req[bool];close cli μα .!ping;?pong; α μα .resp[ping];req[pong]; α serv Use { req , resp } instead of { ! , ? } Duality: Duality: ! v ; S =? v ; S & { l i : S i } = ⊕ { l i : S i } ? v ; S =! v ; S ⊕ { l i : S i } = & { l i : S i } P serv = P cli P cli = P serv µ α .S = µ α .S [ α / α ] close = close Duality is too complex to have in Duality is much simpler and OCaml type type-inference friendly 8
Session-type inference in Session-ocaml let eqclient () = connect_ eqch (fun () -> send (123, 456) >> let%s ans = recv () in close ()) () 9
Session-type inference in Session-ocaml let eqclient () = connect_ eqch (fun () -> send (123, 456) >> proactive let%s ans = recv () in close ()) () req cli (Client) resp 9
Session-type inference in Session-ocaml let eqclient () = connect_ eqch (fun () -> send (123, 456) >> proactive let%s ans = recv () in close ()) () req (req[int*int]; cli resp[bool]; (Client) resp close) cli 9
Session-type inference in Session-ocaml let eqclient () = connect_ eqch (fun () -> send (123, 456) >> proactive let%s ans = recv () in close ()) () req (req[int*int]; cli resp[bool]; (Client) resp close) cli inferred val eqch: req[int*int];resp[bool];close (protocol type) 9
Session-type inference in Session-ocaml let eqserv () = let eqclient () = accept_ eqch (fun () -> connect_ eqch (fun () -> let%s x,y = recv () in send (123, 456) >> proactive send (x=y) >> let%s ans = recv () in close ())) () close ()) () req (req[int*int]; cli resp[bool]; (Client) resp close) cli inferred val eqch: req[int*int];resp[bool];close (protocol type) 9
Session-type inference in Session-ocaml let eqserv () = let eqclient () = accept_ eqch (fun () -> connect_ eqch (fun () -> let%s x,y = recv () in reactive send (123, 456) >> proactive send (x=y) >> let%s ans = recv () in close ())) () close ()) () req (req[int*int]; cli serv resp[bool]; (Client) resp (Server) close) cli inferred val eqch: req[int*int];resp[bool];close (protocol type) 9
Session-type inference in Session-ocaml let eqserv () = let eqclient () = accept_ eqch (fun () -> connect_ eqch (fun () -> let%s x,y = recv () in reactive send (123, 456) >> proactive send (x=y) >> let%s ans = recv () in close ())) () close ()) () (req[int*int]; req (req[int*int]; cli serv resp[bool]; resp[bool]; (Client) resp (Server) close) serv close) cli inferred val eqch: req[int*int];resp[bool];close (protocol type) 9
Session-type inference in Session-ocaml let eqserv () = let eqclient () = accept_ eqch (fun () -> connect_ eqch (fun () -> let%s x,y = recv () in reactive send (123, 456) >> proactive send (x=y) >> let%s ans = recv () in close ())) () close ()) () (req[int*int]; req (req[int*int]; cli serv resp[bool]; resp[bool]; (Client) resp (Server) close) serv close) cli duality is checked inferred by type equality val eqch: req[int*int];resp[bool];close (protocol type) 9
Recommend
More recommend