Sunday, February 24, 2013

Pet Pensiveness

We had to euthanize a family pet yesterday, a 55 pound labrador mix we named Molly. Molly had a great many qualities one looks for in a dog: she was submissive, rarely barked except when asked to or when she thought she was defending us. She was as attached to us as we were to her.

When we first found her, she was said to be the last of her litter - a runt no one else chose. We were told her other parent may have been a shepherd mix, but whatever her heritage she bore an uncanny resemblance to an oversized Finnish Spitz.

Molly had a sort of melancholy disposition from the start, as if she had felt abandoned. As she grew up we found her to be calm, obedient, and sociable on one hand, but when she switched it on her playfulness was almost wolf-like.

My waking moments were filled with memories, and one simple thought. So many people try to focus out on vanishingly distant, imaginary end-points, seeking rigid modes of thinking and to maintain narrow perpectives, racing so hard and fast yet giving so little thought to where they are going - under these conditions the lateral realities that pervade and indeed ground our lives become a blur that is easier to ignore.

Monday, February 4, 2013

GIT-ified views

When I first discovered Distributed Version Control Systems (DVCS), one of the few open source implementations available was Tom Lord's Arch, or tla. Arch was a direct predecessor to Bazaar, a spiritual parent to DARCS, and preceded GIT by about 4 years. The ground being plowed up by these projects, Linus re-envisioned the whole-changeset implementation and added a core audience in the form of the Linux Kernel project. It also didn't hurt that GIT's speed and space efficiency was better.

Coming out of an environment that used Rational's ClearCase, I found it useful to emulate the "set view" functionality using carefully constructed shell functions that could set up or reuse working trees on demand, separate from the repositories. A child login shell was launched to establish a repo-specific environment, and the environment curried to include tla command wrappers with defaulted common command arguments (tla was excessively verbose). I called the resulting wrapper Setview, after the ClearCase command.

The ClearCase feature provided a measure of process- and filesystem- isolation to the development cycle. This was probably deemed to be important to lawyers, who wanted to micromanage what every person could see. Never mind that they probably relied upon tons of GNU copylefted code, but I digress. There are still times when, instead of a stash or a branch/commit/checkout/branch, or cloning a repo a second time, I'd like to just have a transient, isolated instance of the working tree.

And I have to ask myself, "why?"

A decoupled working tree can more easily be automatically garbage collected. When I create temporary and intermediate files in such an ephemeral tree, I don't have to be concerned with clutter: it will go away on its own when I discard the view.

If the repo is decoupled from the working tree, that is, not in a .git subdirectory, the working tree can be destroyed accidentally without risk of destroying the repo. This is mitigated by a frequent cycle of pushing to a remote.

Switching working contexts is something every software developer has to do, especially when working in an institution with multiple internal clients. A pre-configured shell environment, launched when starting a task, and cleaned up when the task is finished, is a useful device for establishing context. It gives a sense of space, boundaries and structure, which is an illusion but helps keep work and thought processes organized.

Having common commands and options curried into wrapper functions is helpful. I find git to be less verbose than tla, but the inconsistency and whacked out grammar in the git command line interface is still a challenger to tla for the most obfuscated command line contest. Still, having aliases, functions, and some environmental variables set per view allows tools to be configured based on the task at hand rather than globally or per repo. An extremely simple example, but very pleasant, is to be able to go snooping around other directories and then just lcd (local cd) to somewhere in the $VIEWHOME. I know pushd/popd offers similar functionality, but it isn't quite the same and lcd is shorter.

For whatever its benefits, having wrappers for git seems a necessity, be they scripts, aliases, functions, or whatever. Having wrappers coupled to the working context, and not coupled to the repo or the users' login environment, is useful for ensuring good isolation and control over configurations.

I don't know if those are good enough reasons for re-implementing a more robust version of setview for git, but sooner or later it seems like I must.

Sunday, February 3, 2013

A note about meaningful gestures

A family member and her husband stopped by to visit briefly for a few hours while travelling for a vacation. They treated us to lunch, during which I asked how her kids were doing. She said "Thanks for asking," with some delight. My wife observed/opined later on in the day that this was very appreciated.

That caught my attention, and made me reflective. I mean, more reflective than usual. For a variety of reasons I have lost touch with a lot of people over my life. But it is more poignant when they were close relationships.

Not long ago told a Meetup group co-organizer I was considered leaving the group. It was nothing personal - it just seemed like time to move on and I felt spent. She remarked that in her opinion it was a bad idea, and that I may not understand the value of the network I had there. My reaction was that, this may be true - I may not fully appreciate what I do have in that network - but at the same time so very often it feels (for reasons that presently escape me) that I cannot effectively leverage that network in a meaningful way. I am "there" but not moving with the flow, like a phantom. I can observe but I'm hardly able to respond in real time or interact in a way that causes substantive growth personally or in the relationships.

I have felt the same way about many of my family relations for most of my life. It is pretty painful, actually.

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.