definitions. To keep to the point, we focus on a core language with monomorphic types and type checking. The concrete syntax follows that of OCaml [6], and except for new constructs, we discuss it only briefly. 1.1 Types Apart from the standard types, eff has effect types E and handler types A ) B : A, B, C ::= int bool unit empty (type) A ⇥ B A + B A ! B E A ) B, E ::= effect ( operation opi : Ai ! Bi)i end. (effect type) In the rule for effect types and elsewhere below (· · · )i indicates that · · · may be re- peated a finite number of times. We include the empty type as we need it to describe exceptions, see Section 6.2. An effect type describes a collection of related operation symbols, for example those for writing to and reading from a communication channel. We write op : A ! B 2 E or just op 2 E to indicate that the effect type E contains an operation op with parameters of type A and results of type B . The handler type A ) B should be understood as the type of handlers acting on computations of type A and yielding computations of type B . 2 “The concrete syntax follows that of OCaml [6], and except for new constructs, we discuss it only briefly.” 1.2 Expressions and computations Eff distinguishes between expressions and computations, which are similar to values and producers of fine-grain call-by-value [7]. The former are inert and free from com- putational effects, including divergence, while the latter may diverge or cause computa- tional effects. As discussed in Section 5, the concrete syntax of eff hides the distinction and allows the programmer to freely mix expressions and computations. Beware that we use two kinds of vertical bars below: the tall separates grammat- ical alternatives, and the short | separates cases in handlers and match statements. The expressions are e ::= x n c true false () (e1, e2) (expression) Left e Right e fun x : A 7! c e # op h, h ::= handler ( ei # opi x k 7! ci)i | val x 7! cv | finally x 7! cf , (handler) where x signifies a variable, n an integer constant, and c other built-in constants. The expressions () , (e1, e2) , Left e , Right e , and fun x : A 7! c are introduction forms for the unit, product, sum, and function types, respectively. Operations e # op and handlers h are discussed in Section 2. The computations are c ::= val e let x = c1 in c2 let rec f x = c1 in c2 (computation) if e then c1 else c2 match e with match e with (x, y) 7! c match e with Left x 7! c1 | Right y 7! c2 e1 e2 1.2 Expressions and computations Eff distinguishes between expressions and computations, which are similar to values and producers of fine-grain call-by-value [7]. The former are inert and free from com- putational effects, including divergence, while the latter may diverge or cause computa- tional effects. As discussed in Section 5, the concrete syntax of eff hides the distinction and allows the programmer to freely mix expressions and computations. Beware that we use two kinds of vertical bars below: the tall separates grammat- ical alternatives, and the short | separates cases in handlers and match statements. The expressions are e ::= x n c true false () (e1, e2) (expression) Left e Right e fun x : A 7! c e # op h, h ::= handler ( ei # opi x k 7! ci)i | val x 7! cv | finally x 7! cf , (handler) where x signifies a variable, n an integer constant, and c other built-in constants. The expressions () , (e1, e2) , Left e , Right e , and fun x : A 7! c are introduction forms for the unit, product, sum, and function types, respectively. Operations e # op and handlers h are discussed in Section 2. The computations are c ::= val e let x = c1 in c2 let rec f x = c1 in c2 (computation) if e then c1 else c2 match e with match e with (x, y) 7! c match e with Left x 7! c1 | Right y 7! c2 e1 e2 new E new E @ e with ( operation opi x @ y 7! ci)i end with e handle c. An expression e is promoted to a computation with val e , but in the concrete syntax