An essay relating a crisis of program modularity in Disk Clock. There follows a brief inquiry into whether the situation is really negative, or simply against the current fad. A technique called Dependency Injection is proposed as a possible solution. The application of the technique is described, leading to a tangent on the Incan language.
Dependency injection is a term that’s been something of a programming buzzword lately (c.f. Google’s Guice) As with many things, I probably wouldn’t have even noticed it, except that I realized I had recently done it, quite by accident and without having heard the term before.
Disk Clock calculates the hours of daylight. (The hours are getting pretty long these days – my bedtime shadow has passed over sundown.) The calculation to do this involves the fraction of the year. It just so happens that I was already calculating this very quantity for the year disk. So the definition of the day disk simply called a method of the year disk – concise and effective, but certainly not modular.
There, of course, came a time when I was looking to pull some generic sections out so I wouldn’t be looking at quite so much code at one time. The astronomical calculations seemed like an obvious candidate – except for that pesky year calculation. Perhaps more insidious, I also directly used the clock’s concept of ‘now’, which had the useful property that anything funny that happened to time (testing daylight savings, etc) would affect the shown daylight – very useful for testing extremes. That bedtime/sundown crossover was a problem in earlier versions, for instance.
Something I realized, I don’t recall if it was during or after, is that the application worked just fine. There was no unnecessary code duplication for the sake of modularity, and information got where it needed to be. This aspect of the code had a certain compactness, folded in upon itself until the parts became inseparable, like a living system.
Somehow, perhaps through the action of selective memory, I remember my early programming being a lot more fun and a lot less anxious. These days it’s quite a regular occurrence to find myself tied in mental knots – and not making progress – trying to work out some aspect of logical purity or maintain a strict dependancy hierarchy.
A Density of Centers
This property of intertwined, cross-supporting features reminded me of Christopher Alexander’s definition of ‘life’. After thinking about buildings (and carpets) for a long time, Alexander came to the conclusion that the best way to talk about the difference between things which are good and things which are not so good is in their density of centers – identifiable points and features (or lack of features) that the mind can notice. Centers work best at high density, operating at multiple levels of scale at once, interacting with and supporting each other.
Making code modular usually involves making sure it isn’t interacting with anything else. Does this preclude living code?
Dependency Injection: This Won’t Hurt a Bit
One of the possible answers to the modularity dilemma is dependency injection. Rather than writing a module to use a support service directly, the module is designed so that a function, object (or whole module in higher level languages) takes the required functions/objects/modules as parameters. In principal this demands clearer boundaries, and in in particular makes testing easier because mock objects can be easily substituted. On the other side of the modularity coin, you’ve exposed some of the inner workings and created a new interface to maintain.
The astronomy module needs a shot of ‘now’ to get going. Technically it takes a function returning a date object. (At first it worked with the same seconds-since-1970 that Disk Clock does, but the time zone information ended up coming in handy.) The astronomy calculations are using DC’s clock again, but now it’s coming by parameter instead of by global reference. The fraction of year calculation isn’t being injected – it’s too simple and has little prospect for application customization, so it just got duplicated.
Space and Time, Sitting in a Tree…
The daylight calculations also depend on latitude and longitude. (I have to estimate this, or just punt. Wouldn’t it be nice if place were an operating system service just like date & time? If someone hooked up a GPS device, applications would get live update for free.) These get passed in as well, although they are more along the line of traditional parameters. The astronomy module constructs a time-place object, which is then used to provide the relevant calculations.
This object is called pacha, a Quechua (Incan) word meaning roughly “time ground place” (Source: William Sullivan, “The Secret of the Incas”, New York: Three Rivers Press, 1996) In the Quecha view of the world, a place at a different time is a different ‘place’. Certainly the place where you are sitting now was quite different when the Incan empire was at it’s height. And certainly this place at that time (and at this time) is very different from the Incan homeland at the same time. Since both axis can change, Quechua doesn’t make a hard distinction between them.
Actually pacha isn’t quite the right word for my program object, since time here is a function, and a pacha is a certain place at a certain time. You could certainly get a constant time by passing in the appropriate function.
(First notes 2008-02-16; most writing 2008-06-05,17,27,28,29.)