Functional Programming – Modeling Entities with Identity and Mutable Persistent State

functional programmingobject-oriented

In an answer to this question (written by Pete) there are some considerations about OOP versus FP. In particular, it is suggested that FP languages are not very suitable for modelling (persistent) objects that have an identity and a mutable state.

I was wondering if this is true or, in other words, how one would model objects in a functional programming language. From my basic knowledge of Haskell I thought that one could use monads in some way, but I really do not know enough on this topic to come up with a clear answer.

So, how are entities with an identity and a mutable persistent state normally modelled in a functional language?

Here are some further details to clarify what I have in mind. Take a typical Java application in which I can (1) read a record from a database table into a Java object, (2) modify the object in different ways, (3) save the modified object to the database.

How would this be implemented e.g. in Haskell? I would initially read the record into a record value (defined by a data definition), perform different transformations by applying functions to this initial value (each intermediate value is a new, modified copy of the original record) and then write the final record value to the database.

Is this all there is to it? How can I ensure that at each moment in time only one copy of the record is valid / accessible? One does not want to have different immutable values representing different snapshots of the same object to be accessible at the same time.

Best Answer

The usual way to go about state changes in a pure language like Haskell is to model them as functions that take the old state and return a modified version. Even for complex objects, this is efficient because of Haskell's lazy evaluation strategy - even though you are syntactically creating a new object, it is not copied in its entirety; each field is evaluated only when it is needed.

If you have more than a few local state changes, things can become clumsy, which is where monads come in. The monad paradigm can be used to encapsulate a state and its changes; the textbook example is the State monad that comes with a standard Haskell install. Note, however, that a monad is nothing special: it's just a data type that exposes two methods (>>= and return), and meets a few expectations (the 'monad laws'). Under the hood, the State monad does exactly the same: take the old state and return a modified state; only the syntax is nicer.