How Functional Programming Is A Bit Like Wandering Around In The Dark.
When I was younger my uncle would tell me stories about caving. He’s really into getting together with a group of friends and going into the dark with a load of equipment, and wandering around looking for an exit. I always imagined how strangely disorientating it must be to move through these caves with your headlamp only illuminating the surfaces around you, with everything in front and behind in total — utter darkness.
This situation has a fun allegory in functional programming — and it may seem to be the notion that you are lost looking for an exit or solution to a seemingly intractable problem — but I’m of course referring to the list data-structure. Moving through a list in a functional language we can only use the list-head…and the rest. The value at the front can be inspected and viewed, but must then be removed, to access the next element in the list. This is one of the most fascinating elements of functional languages — because of the recursion utilised within their data structures — only the first part of the list can be accessed…and then the next first part…and the next first part.
How is this different to imperative programming — and why should anyone care?! From the outside functional programming appears to be something like a reclusive yet ultimately benign cult. The intellectual demand is high and the programming benefits and real-world pay-off off-putting. I am poorly qualified to discuss the subject to the level of an expert Haskell programmer — I’ve never even written anything ‘useful’ in Miranda — but the advantages of the paradigm are becoming clearer, and increasingly elegant.
What we are really doing in purely functional languages like Miranda and Haskell is trying to create ways to move control flow between these dark caverns of inaccessible data. At some point a condition is met, and because of the lazy evaluation in functional languages we turn the headlamp and begin moving down a different tunnel, knowing there is an unevaluated, dark expanse that goes unexplored and unseen. It is worth noting that here we also receive a runtime efficiency, as the compiled datastructure goes ‘lazily’ unexplored. This is both a good way to avoid potential errors but also potential side-effects. The less stuff that gets run the less can go wrong.
Encapsulating code within functions also encourages a stylistic realignment. When writing code functionally we ultimately concentrate more on ‘what we’re doing’ rather than ‘to what’. This seems almost glib in it’s ‘well, duh’ obviousness but it encourages you to question abstraction for abstraction’s sake — and arguably leads to tighter code.
It has been really interesting being exposed to a new paradigm in programming, and its a thought experiment that’s led me to approach programming in a different way, so I encourage anyone who’s never had the opportunity to have a play around with a functional language — even if you never use it, it will lead you to question your assumptions about how you structure programs. Anyway, I better get back to caving….or, as a good friend and much better programmer than me insists I call it (because it’s his favourite word) ‘spelunking’.