
c Kluwer Academic Publishers Boston Manufactured in The Netherlands State in Haskell JOHN LAUNCHBURY jlcseogiedu Oregon Graduate Institute PO Box Portland OR SIMON L PEYTON JONES simonp jdcsglasgowacuk University of Glasgow G QQ Scotland Abstract Some algorithms make critical internal use of up datable state even though their external sp ecication is purely functional Based on earlier work on monads we present a way of securely encapsulating stateful computations that manipulate multiple named mutable ob jects in the context of a nonstrict purelyfunctional language The security of the encapsulation is assured by the type system using parametricity The same framework is also used to handle inputoutput op erations state changes on the external world and calls to C Introduction Purely functional programming languages allow many algorithms to b e expressed very concisely but there are a few algorithms in which inplace up datable state seems to play a crucial role For these algorithms purelyfunctional languages which lack up datable state app ear to b e inherently inecient Ponder McGeer Ng Examples of such algorithms include Algorithms based on the use of incrementallymodied hash tables where lo okups are interleaved with the insertion of new items The unionnd algorithm which relies for its eciency on the set representa tions b eing simplied each time the structure is examined Many graph algorithms which require a dynamically changing structure in which sharing is explicit so that changes are visible nonlo cally There is furthermore one absolutely unavoidable use of state in every functional program inputoutput The plain fact of the matter is that the whole purp ose of running a program functional or otherwise is to make some change to the world an up dateinplace if you please In many programs these IO eects are rather complex involving interleaved reads from and writes to the world state We use the term stateful to describ e computations or algorithms in which the programmer really do es want to manipulate up datable state What has b een lacking until now is a clean way of describing such algorithms in a functional lan guage esp ecially a nonstrict one without throwing away the main virtues of functional languages indep endence of order of evaluation the ChurchRosser prop erty referential transparency nonstrict semantics and so on 2 In this pap er we describ e a way to express stateful algorithms in nonstrict purely functional languages The approach is a development of our earlier work on monadic IO and state encapsulation Launchbury Peyton Jones Wadler but with an imp ortant technical innovation we use parametric p olymorphism to achieve safe encapsulation of state It turns out that this allows mutable ob jects to b e named without losing safety and it also allows inputoutput to b e smo othly integrated with other state manipulation The other imp ortant feature of this pap er is that it describ es a complete system and one that is implemented in the Glasgow Haskell compiler and freely available The system has the following prop erties Complete referential transparency is maintained At rst it is not clear what this statement means how can a stateful computation b e said to b e referentially transparent To b e more precise a stateful computation is a state transformer that is a function from an initial state to a nal state It is like a script detailing the actions to b e p erformed on its input state Like any other function it is quite p ossible to apply a single stateful computation to more than one input state and of course its b ehaviour may dep end on that state But in addition we guarantee that the state is used in a singlethreaded way Consequently the nal state can b e constructed by mo difying the input state inplace This ecient implementation resp ects the purelyfunctional seman tics of the statetransformer function so all the usual techniques for reasoning ab out functional programs continue to work Similarly stateful programs can b e exp osed to the full range of program transformations applied by a compiler with no sp ecial cases or side conditions The programmer has complete control over where inplace up dates are used and where they are not For example there is no complex analysis to determine when an array is used in a singlethreaded way Since the viability of the entire program may b e predicated on the use of inplace up dates the programmer must b e condent in and b e able to reason ab out the outcome Mutable ob jects can b e named This ability sounds inno cuous enough but once an ob ject can b e named its use cannot b e controlled as readily Yet naming is imp ortant For example it gives us the ability to manipulate multiple mutable ob jects simultaneously Inputoutput takes its place as a sp ecialised form of stateful computation In deed the type of IOp erforming computations is an instance of the more p olymorphic type of stateful computations Along with IO comes the ability to call imp erative pro cedures written in other languages It is p ossible to encapsulate stateful computations so that they app ear to the rest of the program as pure stateless functions which are guaranteed by the 3 type system to have no interactions whatever with other computations whether stateful or otherwise except via the values of arguments and results of course Complete safety is maintained by this encapsulation A program may contain an arbitrary number of stateful subcomputations each simultaneously active without concern that a mutable ob ject from one might b e mutated by another Stateful computations can even b e p erformed lazily without losing safety For example supp ose that stateful depthrst search of a graph returns a list of vertices in depthrst order If the consumer of this list only evaluates the rst few elements of the list then only enough of the stateful computation is executed to pro duce those elements Overview This section introduces the key ideas of our approach to stateful computation We b egin with the programmerseyeview State transformers A state transformer of type ST s a is a computation which transforms a state indexed by type s and delivers a value of type a You can think of it as a pure function taking a state as its argument and delivering a state and a value as its result We depict a state transformer like this Result State in State out From a semantic p oint of view this is a purelyfunctional account of state For example b eing a pure function a state transformer is a rstclass value it can b e passed to a function returned as a result stored in a data structure duplicated freely and so on Of course it is our intention that the new state will actually b e constructed by mo difying the old one in place a matter to which we return in Section From now on we take the term state transformer to b e synonymous with stateful computation the computation is seen as transforming one state into another A state transformer can have other inputs b esides the state if so it will have a functional type It can also have many results by returning them in a tuple For example a state transformer with two inputs of type Int and two results of type Int and Bool would have the type 4 Int Int ST s IntBool Its picture might lo ok like this Inputs Results State in State out The simplest state transformer returnST simply delivers a value without aecting the state at all returnST a ST s a The picture for returnST is like this State in State out Mutable variables Next we need to provide some primitive state transformers which op erate on the state The simplest thing to provide is the ability to allo cate read and write mutable variables newVar a ST s MutVar s a readVar MutVar s a ST s a writeVar MutVar s a a ST s The type MutVar s a is the type of references allo cated from a state indexed by s and containing a value of type a A reference can b e thought of as the name of or address of a variable an up datable lo cation in the state capable of holding a value The state contains a nite mapping of references to values Notice that unlike SMLs ref types for example MutVars are parameterised over the type of the state as well as over the type of the value to which the reference is mapp ed by the state a decision whose imp ortance will b ecome apparent in Section We use the name MutVar for the type of references rather than Ref sp ecically to avoid confusion with SML Returning to the primitives the function newVar takes an initial value of type a say and delivers a state transformer of type ST s MutVar s a When this 5 state transformer is applied to a state it allo cates a fresh reference that is one currently not used in the state augments the state to map the new reference to the supplied value and returns the reference along with the mo died state Given a reference v readVar v is a state transformer which leaves the state unchanged but uses the state to map the reference to its value The function writeVar transforms the state so that it maps the given reference to a new value Notice that the reference itself does not change it is the state which is mo died writeVar delivers a result of the unit type a type which only has one value apart from b ottom also written A state transformer of type ST s is useful only for its eect on the state Comp osing state transformers State transformers can b e comp osed in sequence to form a larger state transformer using thenST which has type thenST ST s a a ST s b ST s b The picture for s thenST s is like this s1 s2 State in State out Notice
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages51 Page
-
File Size-