Saturday, February 2, 2013

Cultured Software, Part III

Over the last two posts I obliquely drove from venting about PHP to discussing software as virtual fecal matter, went on to compare refactoring to composting, and finally introduced what I think of as Fixed Points.

This post is to expand upon the idea of a fixed point, which is a little more formal than a metaphor and a lot less rigorous than its algebraic namesake.

It is often helpful when generalizing to enumerate cases and examine concrete examples, and to think inductively.  Make a list. What might be some fixed points? I'm working with database and Web applications right now, and these surface details spring to mind:
  • Database connection details entrained in code: user names, passwords, literal database names, and such. 
  • Links between files, as by an inclusion construct, addressed via filesystem paths.
  • Queries that are substantially or exactly repeated (unDRY).
  • Explicit non-reflection.
    References to 
    properties, columns, fields... any explicit (re-)enumeration of the element parts of an abstract whole. The challenge here is that when there is a high degree of correspondence between structures, referring to  discrete elements may be  simpler, clearer, and more efficient to express than referring to the whole.
  • Gratuitous Typing.
    Types assigned to a resource a
    re fixed points even if they are not repeated.
    For instance, if we assume all image resources are in JPEG format, we constrain the set of mime types, conventional file names, suitable rendering mediums, and salient libraries. Or when we assign a precise length to a data field when no particular length is demanded by the problem. I refer to such assignment of types as "gratuitous," not because there isn't some utility -- these are sensible techniques for ensuring performance criteria and reducing the decision space -- but because often languages which encourage static typing are designed so as to force the choice of assigning types (even if they are weak types) and have few or no facilities for laziness in evaluation or for adaptive interfaces.
  • Positionally addressed fielded data (falls into the category of gratuitous typing). 
  • Code modules included from an external authoritative source may be a fixed point, assuming that there will always be some reason to incorporate updates made to the external module. 
  • Cut-and-pasted 
    • content
    • algorithms
    • code
Assumptions and inexpressive syntaxes give rise to fixed points. I'm distinguishing here between meaningful symmetry points, and gratuitous fixed points that break symmetry. Facts that aren't necessary to be explicitly represented in code but are there anyway, are fixed points.

It could be freakishly hard to understand code if it was all written in Ruby metacode style, or used overly generic labels for every data structure or function. Yet overly literal styles of coding necessarily over-constrain problems while under-expressing the solution intent.  Over reliance upon metaprogramming can be hyperoptic, but being too concrete is myopic: the stakeholder is presented with evolutionary dead-ends, the developer with death by a thousand asymmetric cuts.

Fixed points present constraints upon the contexts for which the intents expressed in the code are valid. 

Fixed points may also be false invariants. What matters is not the sensitivity to change, although fixed points seem to be facts and conditions that change slowly or at poorly understood intervals. What matters is that the assumptions underlying fixed points can change, which in turn adds rigidity and induces fractures in the structure of a codebase.

No comments: