Effect handler oriented programming Sam Lindley The University of Edinburgh and Imperial College London 18th February 2020
Part I Prologue
C E K R e l a t i o n a l L i n k s Ma c h i n e L e n s e s Q u e r y ( S e r v e r ) http://www.links-lang.org S h r e d d i n g C P S L i n k i n g t h e o r y t o p r a c t i c e T r a n s l a t i o n f o r t h e w e b Database Effect ( C l i e n t ) L a n g u a g e - Integration Handlers I n t e g r a t e d Q u e r y R o w - b a s e d E fg e c t s P r o v e n a n c e WeB Interactive Wi t h t h a n k s t o S i m o n F o w l e r Development Programming T y p e d Concurrency & Distribution H T ML + a n t i q u o t e s N o t e b o o k P r o g r a mmi n g F o r ml e t s Mo d e l - R P C S e s s i o n V i e w - C a l c u l u s D i s t r i b u t e d T r y L i n k s U p d a t e E x c e p t i o n s S e s s i o n T y p e s
Part II Effect handler oriented programming
Effects Programs as black boxes (Church-Turing model)?
Effects Programs must interact with their environment
Effects Programs must interact with their environment Effects are pervasive ◮ input/output user interaction ◮ concurrency web applications ◮ distribution cloud computing ◮ exceptions fault tolerance ◮ choice backtracking search
Effects Programs must interact with their environment Effects are pervasive ◮ input/output user interaction ◮ concurrency web applications ◮ distribution cloud computing ◮ exceptions fault tolerance ◮ choice backtracking search Typically ad hoc and hard-wired
Effect handlers Deep theory Gordon Plotkin Matija Pretnar Handlers of algebraic effects, ESOP 2009
Effect handlers Deep theory Gordon Plotkin Matija Pretnar Handlers of algebraic effects, ESOP 2009 Composable and user-defined interpretation of effects in general
Effect handlers Deep theory Gordon Plotkin Matija Pretnar Handlers of algebraic effects, ESOP 2009 Composable and user-defined interpretation of effects in general Give programmer direct access to environment (c.f. resumable exceptions, monads, delimited control)
Effect handlers Deep theory Gordon Plotkin Matija Pretnar Handlers of algebraic effects, ESOP 2009 Composable and user-defined interpretation of effects in general Give programmer direct access to environment (c.f. resumable exceptions, monads, delimited control) Growing industrial interest JavaScript UI library (used by > 1 million websites) React Probabilistic programming language (statistical inference) Pyro Semantic Code analysis library ( > 4 . 5 million Python repositories)
Example 1: choice and failure Effect signature { choose : 1 ⇒ Bool , fail : a . 1 ⇒ a }
Example 1: choice and failure Effect signature { choose : 1 ⇒ Bool , fail : a . 1 ⇒ a } Drunk coin tossing toss () = if choose () then Heads else Tails drunkToss () = if choose () then if choose () then Heads else Tails else fail () drunkTosses n = if n = 0 then [] else drunkToss () :: drunkTosses ( n − 1)
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x � fail () � �→ Nothing
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x � choose () → r � �→ r True
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] � choose () → r � �→ r True + + r False
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] handle 42 with allChoices = ⇒ [42] � choose () → r � �→ r True + + r False handle toss () with allChoices = ⇒ [Heads , Tails]
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] handle 42 with allChoices = ⇒ [42] � choose () → r � �→ r True + + r False handle toss () with allChoices = ⇒ [Heads , Tails] handle ( handle drunkTosses 2 with maybeFail) with allChoices = ⇒
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] handle 42 with allChoices = ⇒ [42] � choose () → r � �→ r True + + r False handle toss () with allChoices = ⇒ [Heads , Tails] handle ( handle drunkTosses 2 with maybeFail) with allChoices = ⇒ [Just [Heads , Heads] , Just [Heads , Tails] , Nothing , Just [Tails , Heads] , Just [Tails , Tails] , Nothing , Nothing]
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] handle 42 with allChoices = ⇒ [42] � choose () → r � �→ r True + + r False handle toss () with allChoices = ⇒ [Heads , Tails] handle ( handle drunkTosses 2 with maybeFail) with allChoices = ⇒ [Just [Heads , Heads] , Just [Heads , Tails] , Nothing , Just [Tails , Heads] , Just [Tails , Tails] , Nothing , Nothing] handle ( handle drunkTosses 2 with allChoices) with maybeFail = ⇒
Example 1: choice and failure Handlers maybeFail = — exception handler return x �→ Just x 42 with maybeFail = ⇒ Just 42 handle � fail () � �→ Nothing handle fail () with maybeFail = ⇒ Nothing trueChoice = — linear handler return x �→ x handle 42 with trueChoice = ⇒ 42 � choose () → r � �→ r True handle toss () with trueChoice = ⇒ Heads allChoices = — non-linear handler return x �→ [ x ] handle 42 with allChoices = ⇒ [42] � choose () → r � �→ r True + + r False handle toss () with allChoices = ⇒ [Heads , Tails] handle ( handle drunkTosses 2 with maybeFail) with allChoices = ⇒ [Just [Heads , Heads] , Just [Heads , Tails] , Nothing , Just [Tails , Heads] , Just [Tails , Tails] , Nothing , Nothing] handle ( handle drunkTosses 2 with allChoices) with maybeFail = ⇒ Nothing
Small-step operational semantics for (deep) effect handlers Reduction rules let x = V in N � N [ V / x ] handle V with H � N ret [ V / x ] handle E [op V ] with H � N op [ V / p , ( λ x . handle E [ x ] with H ) / r ] , op # E where H = return x �→ N ret � op 1 p → r � �→ N op 1 · · · � op k p → r � �→ N op k Evaluation contexts E ::= [ ] | let x = E in N | handle E with H
Example 2: cooperative concurrency (static) Effect signature { yield : 1 ⇒ 1 }
Example 2: cooperative concurrency (static) Effect signature { yield : 1 ⇒ 1 } Two cooperative lightweight threads tA () = print (“A1 ”); yield (); print (“A2 ”) tB () = print (“B1 ”); yield (); print (“B2 ”)
Recommend
More recommend