CONCURRENCY AND TYPES IN PROGRAMMING Luís Caires Universidade Nova de Lisboa (based on work with Seco, Militão, Aldrich) NOVA Laboratory for Computer Science and Informatics OPCT 2014 Bertinoro Italy
types in programming Types at the heart of standard PLs (OCaml, Java,C#,Scala) Foundations in logic (a type system = a specialized logic) Highly modular, based on a “lego” of canonic constructions Still, “standard” types easy to use by common programmers Big impact on software quality (“WTP do not go wrong”) Big impact on programming discipline (“tame programmers”) Clearly a success story for theory / foundational research But what about programming with concurrency ?
typing concurrent programming A program in a typed concurrent programming language should not go wrong ! Unfortunately, it is still very hard to ensure it does not. Many relevant contributions from the community: Many specific type systems for abstract models (pi, ambients) and properties (deadlock freedom, race absence, fidelity) Emphasis on message passing (communication, sessions) Often, introduced concepts are neither easy to transfer to “useful” programming languages or to (the engineers) minds But even harder with general logics (so we stick to types)
a challenge May one do for concurrent programming something like “classical type theory" did for general programming? What could be the core ingredients of a scalable and reasonably general type theory for concurrency? Insights from process algebra and (sub)structural logics, suggest that notions of behavioral types may help to provide a uniform foundation for typing concurrent programs “the essence of concurrency is interference” (also in aliasing) In this talk, I discuss a bit this (not so recent) view, illustrating with some recent [popl’13,ecoop’14] and ongoing work
a challenge May one do for concurrent programming something like “classical type theory" did for general programming? What could be the core ingredients of a scalable and reasonably general type theory for concurrency? Insights from process algebra and (sub)structural logics, suggest that notions of behavioral types may help to provide a uniform foundation for typing concurrent programs “the essence of concurrency is interference” (also in aliasing) In this talk, I discuss a bit this (not so recent) view, illustrating with some recent [popl’13,ecoop’14] and ongoing work
programming language ::= ( Variable) e, f x | λ x.e ( Abstraction) | ( Application) e 1 e 2 | let x = e 1 in e 2 ( Definition) | ref ( Heap cell alloc) | ( Heap cell free) free e | a := e ( strong Update ) | ! a ( Dereference) | [ l 1 = e 1 | . . . ] ( Tuple) | ( Selection) e.l | if ( e 1 == e 2 ) as x e 3 else e 4 ( Match) | # l ( e ) ( Variant) | case e of # l i ( x i ) → e i ( Conditional) | fork e ( New thread) | ( Wait) wait e | ( resource bundle) res a in e | open ( a ) ( enter bundle) | close ( a ) ( leave bundle)
a queue ADT let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ]
typical queue configurations let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ # N enq = · · · | deq = · · · ] # F ( ) # N tl hd
typical queue configurations let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ # L ( ) # L ( ) # N enq = · · · | deq = · · · ] # L ( ) hd # H ( ) tl
queue Node code let newNode = λ [] . var nxt := # N in res n in [ setNxt = λ p. ( open n ; nx := # L ( p ); close n ) | getNxt = open n ; let p =! nxt in ( close n ; p ) | disp = ( open n ; free nxt ; close n ) ]
enqueue operation code enq = let n = ( newNode nil ) in ( open s ; case hd of # H ( hv ) → ( hv . setNxt ( n ); hd := # H ( n )) # F ( fn ) → ( fn . setNxt ( n ); hd := # H ( n ); tl := fn ); close s )
dequeue operation code deq = open s ; case hd of # F ( fn ) → hd := # F ( fn ) # H ( hv ) → ( case tl. getNxt of # N → nil # L ( tv ) → ( tl. disp ; if ( hv == tv ) as u ( hd := # F ( u )) else ( hd := # H ( hv ); tl := tv )); close s
client code let q = newQueue () in let t 1 = fork ( rec ( X ) .q. enq ; X ) in let t 2 = fork ( rec ( X ) .q. dec ; X ) in ( wait t 1 ; wait t 2 )
structural types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ] newQueue : 0 → [ enq = 0 | dec = 0]
behavioral types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ] newQueue : !(0 | → rec ( X ) . ( enc N deq ; X ))
behavioral types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ] newQueue : 0 → rec ( X ) . ( enc N deq ; X )
behavioral types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ] newQueue : 0 → rec ( X ) . ( enc ; X ) | rec ( X ) . ( deq ; X )
behavioral types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | deq = · · · ] newQueue : 0 → (! enc | ! deq )
behavioral types let newQueue = λ [] . var hd , tl in ( hd := # F ( newNode nil ); tl := # N ; res s in ( [ enq = · · · | Single = hd : rd (# F ( Node )) | tl : rd (# N ) deq = · · · Many = hd : rd (# H ( Hv )) | tl : rd ( Tv ) ] A = ( Single ∨ Many ) ; ( hd : var | tl : var ) s : ρ ( inv ( A ))
type structure
behavioral separation types ::= ( stop) | T | ( function) T, U ! V 0 | ( sequential) | T | U ( parallel) T ; U | T N U ( intersection) | ! T ( shared) | T _ U ( union) | l : T ( field) | � l ∈ I # l : T l ( alternative) | ρ ( A ) ( bundle) | ( isolated) | τ ( T ) ( thread) � T | rec ( X ) T ( recursion) | ( recursion var) X types express safe usage capabilities from client perspective enforces abstraction / information hiding
linear λ -calculus A | x : U ` e : T ! T ( VAbs ) A ` λ x.e : U | A ` e 1 : U | B ` e 2 : U ! T ( App ) A | B ` e 1 e 2 : T � x : T, A � A, B ::= 0 0 ` nil : 0 : B ( A is a subtype of B ) A < A ` e : U ( e yields value of type U under B )
adding dynamics (cf. Hoare types) : B ( A is a subtype of B ) A < A ` z e :: B ( e types from A to z in B ) type assertions (cf. type environments as “global types”): � x : T � A ; B � A | B � A N B � A _ B � ! A � � � � � � � � � A A, B ::= 0
(linear) arrow type A | x : U ` y e :: y : T ! T ( VAbs ) A ` z λ x.e :: z : U | A ` z e 1 :: z : U | B ` x e 2 :: x : U ! T ( App ) A | B ` y e 1 e 2 :: y : T symmetric monoidal closed: ( T, 0 , ( − | − ) , | → )
structural rules A ` x e 1 :: B B ` y e 2 :: C A ` y let x = e 1 in e 2 :: C ( Let / Cut ) x : U ` z x :: z : U ( Id ) A 0 ` x e :: B 0 B 0 < : A 0 : B A < ( Sub ) A ` x e :: B A ` x e :: B A ` x e :: B A | C ` x e :: B | C ( Par ) A ; C ` x e :: B ; C ( Seq )
laws for parallel and sequence U ; ( V ; T ) < > ( U ; V ) ; T : : : U ; 0 < > U 0 ; U < > U U | ( V | T ) < > ( U | V ) | T U | V < > V | U U | 0 < : : : > U : ( A | B ) ; ( C | D ) ( A ; C ) | ( B ; D ) < ( special case ) : A ; D A | D <
sample typing judgments : B ( A is a subtype of B ) A < A ` z e :: B ( e types from A to z in B ) ✔ ( f : U | ! V ; y : U ) | x : U ` z ( f x ) :: z : V ; y : U ✘ ( f : U | ! V ; y : U ) | x : U ` z ( f y ) :: ✔ a : use ` z ( λ x.a := x ) :: z : � U | ! 0 ; a : rd ( � U )
field type A ` x e :: x : U A ` z [ . . . l = e . . . ] :: z : l : U ( Field ) A ` z e :: z : l : T A ` x e.l :: x : T ( Sel )
(linear) intersection type A ` y e :: B A ` y e :: C : U U N V < ( And ) A ` y e :: B N C : V U N V < A ` y e :: B 1 N B 2 ( AndE ) : U N U U < A ` y e :: B i unlabeled choice (e.g., exporting multiple interfaces) examples: A ` [ up = e 1 | dn = e 2 ] :: x :( up : 0 N dn : 0 )
separation types 0 ` y v :: 0 ( VStop ) A ` y v :: C B ` y v :: D ( VSeq ) A ; B ` y v :: C ; D A ` y v :: C B ` y v :: D ( VPar ) A | B ` y v :: C | D concurrent Kleene algebra: ( T, ( − N − ) , ( − | − ) , ( − ; − ) , 0 )
(linear) labeled sum type A ` y e c :: y : � l ∈ I # l : T l x i : T i | B ` z e i :: C ( Case ) A | B ` z case e c of # l ( x ) ! e :: C A ` z e :: z : T i ( Option ) A ` z # l i ( e ) :: z : � l ∈ I # l : T l labeled choice (cf. variant type)
(linear) union type A ` z e :: C B ` e :: C ( UnionCase ) A _ B ` z e :: C A ` z e :: z : T i ( InUnion ) A ` z e :: z : _ l ∈ I T l unlabeled union (e.g., exporting some interface) examples: s : rec ( X ) . ( empty ?:# T ; push ∨ empty ?:# F ; ( pop N push ) ; X )
types for sharing and isolation ! A 1 | . . . | ! A n ` x v :: B ! A 1 | . . . | ! A n ` x v ::! B ( VShr ) � A 1 | . . . | � A n ` x e :: B � A 1 | . . . | � A n ` x e :: � B ( Iso ) monoidal co-monads: isolated � ( � ) shared !( − )
laws for sharing (cf. linear logic !) ! U < : U : !! U ! U < : ! 0 0 < : !( U | V ) ! U | ! V < ! U < : 0 : ! U | ! U ! U <
Recommend
More recommend