Bricks not monoliths
Chapter 32 of Tao Te Programming advises you to make bricks instead of monoliths. Here is an example. The example is written with the syntax of R and is a data analysis, but the principle is valid no matter what language you use or what your task is.
Monolith
Here is an outline of a function reminiscent of many novice attempts:
monolith <- function (data, col="blue", pch=21) { # transform data # fit model to data # plot data, uses 'col' and 'pch' # get desired model results # return desired model results }
Each of these comment lines may be many lines of code so that the whole function runs to pages. On the positive side, this is a step towards abstraction from merely having a script of commands and changing values by hand within the script.
Brickwall
It is not that I’m against having one function that does everything. What I’m against is all the work being done in that one function. Here is an alternative:
brickwall <- function (data, ...) { tranData <- myDataTransform(data) dataMod <- myModelFit(tranData) myPlot(dataMod, ...) myModelOutput(dataMod) # this value is returned }
brickwall
and monolith
can do exactly the same things, but they do them differently. In the brickwall
setting we have written 5 functions (at least) instead of 1. There is an R-specific difference in the two functions. brickwall
uses R’s three-dots mechanism to make changes to the plots flexible and convenient. On the other hand, monolith
tries to hardcode all of the plotting arguments that the user might want to use.
Advantages
There are several ways that the modular approach helps:
- easier to understand
- easier to debug
- easier to change
- code is more reusable
Easy to understand
It is easy to comprehend what brickwall
is doing. If we saw an actual implementation of monolith
, it would (almost surely) not be at all expressive of what it was really doing. If we are to understand something, it has to be simple. Additionally, when you break a problem into pieces, you are likely to think more clearly about it.
Easy to debug
If something goes wrong in the code, brickwall
is going to be very much easier to debug. We will be able to see in which sub-function it is going wrong — we’ll be able to ignore almost all of the code when we debug.
Easy to change
This is probably the most important point. brickwall
allows us to easily experiment. We can substitute an alternative approach to one (or more) of the sub-functions with minimal effort. Code evolves, make that evolution as easy as possible.
Reusable code
The sub-functions may well find uses in other settings. Instead of rewriting the code or mucking about extracting bits of code from a monolith, you can just use what you already have.
Epilogue
All in all you’re just another brick in the wall
from “Another Brick in the Wall” by Roger Waters
Trackbacks & Pingbacks
[…] Bricks not monoliths – Burns Statistics […]
Leave a Reply
Want to join the discussion?Feel free to contribute!