Fundamentally, all computer programs are a sequence of instructions for a processor. Since machine code is hard to reason about, most computer programs are written at a higher level of abstraction. In this article, I’ll contrast two tools of abstraction, from two different programming paradigms, and talk about how they solve the same problem from opposing perspectives.
The first abstraction tool up on the block is the object. In object-oriented programming, sequences of instructions are hidden inside logical groupings of behaviour. An object describes what it does, and how it does it gets hidden. This is very helpful for reasoning about programs: the interaction of objects can quite directly relate to the interaction of things and ideas in the real world. A Blogger creates Articles, which appear in a Stream: we can already start to imagine what sort of relationships these three objects might have. An object-oriented program passes messages from object to object, causing each one to act out its programmed behaviour.
The second abstraction tool to introduce is the monad. In functional programming, a function is an idempotent transformation from one domain to another, and a functional program is a composition of functions into higher order functions. A transformation takes a value and provides a value, and has no further effect on anything, so if that were the end of the story functional programs couldn’t actually do anything: they’d have no way to interact with the world. Monads are, if I may gloss over a great deal of detail, a sequence of effects that should be caused, such as printing a message to the screen, or reading the current location of the mouse pointer.
Both of these tools provide a way to write programs which express a model of the world, without worrying about how literal the computer processor is. Objects let us model relationships between things, while monads let us model equivalence relationships.
Beyond that, though, both tools provide a way to combine state and behaviour. In our machine code world, there’s a lot of tiny slots in the computer’s memory where values can be stored and retrieved, and most instructions deal with moving these values around in some way. These values are collectively called state: they’re the state the computer is currently in. State makes reasoning about programs hard, because state is not visible in the program’s source code, but it has enormous impacts on the result of running a program.
Object-oriented programming manages the complexity of state by encapsulating it inside objects. Objects should expose only behaviours to each other, so the extent to which a particular piece of state influences a program’s execution can be limited to a unit which can be reasoned about more effectively.
Functional programming manages the complexity of state by not having any. This turns out to be impractical, so monads reintroduce state by wrapping it up as a sequence of computational steps, which also limits the influence of state to a manageable portion of the program.
In object-oriented programming, objects are a tool for imposing behaviour on state, whereas in functional programming, monads are a tool for imposing state on behaviour. Both solve the problem of state getting in the way of reasoning about behaviour, but they both come at the problem from very different directions.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.