A duality between exceptions and states
Jean-Guillaume Dumas, Dominique Duval, Laurent Fousse, Jean-Claude Reynaud
aa r X i v : . [ c s . L O ] D ec A duality between exceptions and states
Jean-Guillaume Dumas ∗ , Dominique Duval † , Laurent Fousse ‡ , Jean-Claude Reynaud § October 24., 2011
AbstractAbstract.
In this short note we study the semantics of two basic computational effects, exceptionsand states, from a new point of view. In the handling of exceptions we dissociate the control from theelementary operation which recovers from the exception. In this way it becomes apparent that there isa duality, in the categorical sense, between exceptions and states.
Introduction
In this short note we study the semantics of two basic computational effects, exceptions and states, from anew point of view. Exceptions are studied in Section 1. The focus is placed on the exception “flags” whichare set when an exception is raised and which are cleared when an exception is handled. We define the exception constructor operation which sets the exception flag, and the exception recovery operation whichclears this flag. States are considered in the short Section 2. Then in Section 3 we show that our point ofview yields a surprising result: there exists a symmetry between the computational effects of exceptions andstates, based on the categorical duality between sums and products. More precisely, the lookup and updateoperations for states are respectively dual to the constructor and recovery operations for exceptions. Thisduality is deeply hidden, since the constructor and recovery operations for exceptions are mixed with thecontrol. This may explain that our result is, as far as we know, completely new.States and exceptions are computational effects : in an imperative language there is no type of states,and in a language with exceptions the type of exceptions which may be raised by a program is not seenas a return type for this program. In this note we focus on the denotational semantics of exceptions andstates, so that the sets of states and exceptions are used explicitly. However, with additional logical tools,the duality may be expressed in a way which fits better with the syntax of effects [Dumas et al. 2010].Other points of view about computational effects, involving monads and Lawvere theories, can be found in[Moggi 1991, Schr¨oder & Mossakowski 2004, Levy 2006, Plotkin & Pretnar 2009]. However it seems difficultto derive from these approaches the duality described in this note.
The syntax for exceptions heavily depends on the language. For instance in ML-like languages there areseveral exception names , and the keywords for raising and handling exceptions are raise and handle , whilein Java there are several exception types , and the keywords for raising and handling exceptions are throw and try-catch . In spite of the differences in the syntax, the semantics of exceptions share many similarities.A major point is that there are two kinds of values: the ordinary (i.e., non-exceptional) values and theexceptions. It follows that the operations may be classified according to the way they may, or may not, ∗ LJK, Universit´e de Grenoble, France.
[email protected] † LJK, Universit´e de Grenoble, France.
[email protected] ‡ LJK, Universit´e de Grenoble, France.
[email protected] § Malhivert, Claix, France.
Exc denote the set of exceptions . The “tagging” processcan be modelled by injective functions t i : Par i → Exc called the exception constructors , with disjoint images:for each index i in some set of indices I , the exception constructor t i : Par i → Exc maps a non-exceptionalvalue (or parameter ) a ∈ Par i to an exception t i ( a ) ∈ Exc . When a function f : X → Y + Exc raises (or throws ) an exception of index i , the following raising operation is called: raise i,Y : Par i → Y + Exc
The raising operation raise i,Y is defined as the exception constructor t i followed by the inclusion of Exc in Y + Exc .Given a function f : X → Y + Exc and an element x ∈ X , if f ( x ) = raise i,Y ( a ) for some a ∈ Par i then one says that f ( x ) raises an exception of index i with parameter a into Y . One says that a function f : X + Exc → Y + Exc propagates exceptions when it is the identity on
Exc . Clearly, any function f : X → Y + Exc can be extended in a unique way as a function which propagates exceptions.Now let us study the handling of exceptions. The process of clearing the “exception tags” can be modelledby functions c i : Exc → Par i + Exc called the exception recovery operations: for each i ∈ I and e ∈ Exc theexception recovery operation c i ( e ) tests whether the given exception e is in the image of t i . If this is actuallythe case, then it returns the parameter a ∈ Par i such that e = t i ( a ), otherwise it propagates the exception e . For handling exceptions of indices i , . . . , i n raised by some function f : X → Y + Exc , one providesa function g i k : Par i k → Y + Exc , which may itself raise exceptions, for each k in { , . . . , n } . Then thehandling process builds a function which propagates exceptions, it may be named try { f } catch i k { g k } ≤ k ≤ n or f handle ( i k ⇒ g k ) ≤ k ≤ n : f handle ( i k ⇒ g k ) ≤ k ≤ n : X + Exc → Y + Exc
Using the recovery operations c i k , the handling process can be defined as follows.For each x ∈ X + Exc , ( f handle ( i k ⇒ g k ) ≤ k ≤ n )( x ) ∈ Y + Exc is defined by:// if x was an exception before the try , then it is just propagated if x ∈ Exc then return x ∈ Exc ⊆ Y + Exc ;// now x is not an exception compute y := f ( x ) ∈ Y + Exc ;if y ∈ Y then return y ∈ Y ⊆ Y + Exc ;// now y is an exception for k = 1 ..n repeatcompute y := c i k ( y ) ∈ Par i k + Exc ;if y ∈ Par i k then return g k ( y ) ∈ Y + Exc ;// now y is an exception but it does not have index i k , for any k ∈ { , . . . , n } return y ∈ Exc ⊆ Y + Exc .Given an exception e of the form t i ( a ), the recovery operation c i returns the non-exceptional value a whilethe other recovery operations propagate the exception e . This is expressed by the equations (1) in Figure 1.Whenever Exc = P i ∈ I Par i with the t i ’s as coprojections, then equations (1) provide a characterization ofthe operations c i ’s. Now let us forget temporarily about the exceptions in order to focus on the semantics of an imperativelanguage. Let St denote the set of states and Loc the set of locations (also called variables or identifiers ).For each location i , let Val i denote the set of possible values for i . For each i ∈ Loc there is a lookup i ∈ I : • a set Par i (parameters) • two operations t i : Par i → Exc (exception constructor)and c i : Exc → Par i + Exc (exception recovery) • and two equations: ( ∀ a ∈ Par i , c i ( t i ( a )) = a ∈ Par i ⊆ Par i + Exc ∀ b ∈ Par j , c i ( t j ( b )) = t j ( b ) ∈ Exc ⊆ Par i + Exc for every j = i ∈ I (1)which correspond to commutative diagrams, where m i and n i are the injections: Par i + Exc Par i m i o o Exc c i O O Par it i o o id O O = Par i + Exc Exc n i o o Par jt j o o Exc c i O O Par jt j o o id O O = Figure 1: Semantics of exceptions: constructor and recoveryoperation l i : St → Val i for reading the value of location i in the given state. In addition, for each i ∈ Loc there is an update operation u i : Val i × St → St for setting the value of location i to the given value, withoutmodifying the values of the other locations in the given state. This is summarized in Figure 2. Whenever St = Q i ∈ Loc
Val i with the l i ’s as projections, two states s and s ′ are equal if and only if l i ( s ) = l i ( s ′ ) foreach i , and equations (2) provide a characterization of the operations u i ’s.For each location i ∈ Loc : • a set Val i (values) • two operations l i : St → Val i (lookup)and u i : Val i × St → St (update) • and two equations: ( ∀ a ∈ Val i , ∀ s ∈ St , l i ( u i ( a, s )) = a ∀ a ∈ Val i , ∀ s ∈ St , l j ( u i ( a, s )) = l j ( s ) for every j = i ∈ Loc (2)which correspond to commutative diagrams, where p i and q i are the projections: Val i × St p i / / u i (cid:15) (cid:15) Val i id (cid:15) (cid:15) St l i / / Val i = Val i × St q i / / u i (cid:15) (cid:15) St l j / / Val j id (cid:15) (cid:15) St l j / / Val j = Figure 2: Semantics of states: lookup and update3
Duality
Our main result is now clear from Figures 1 and 2.
Theorem 3.1.
The duality between categorical products and sums can be extended as a duality between thesemantics of the lookup and update operations for states on one side and the semantics of the constructorand recovery operations for exceptions on the other side.