TDD: For Those Who Don't Know How to Design Software - The Code Whisperer

January 8, 2024 Simple Design, Refactoring, Evolutionary Design, Programming Without Blame

This is a companion discussion topic for the original entry at
1 Like

Thanks, as ever, JB.

I suspect we can even make a stronger claim here. If we accept the notion of program as constructive proof (albeit one with effects–which are deeply confounding compared to the enterprise of mathematics, the theorems of which don’t generate heat when applied, for instance), then refactoring becomes something like a proof that two programs are homotopic (i.e. can be continuously deformed from one into the other).

Analogously, if we think of design as the meta-level work of writing some proof in the first place, then one could reasonably contend that the least interesting results will be the ones we generate without effort; the conjectures are where the action is! From this perspective, there simply is no lofty place from which we can stand, knowing precisely what lemmas (components, perhaps) to write or what existing theorems (say, libraries or services) to rely on.

Finally, as eccentric as some of the most notable mathematicians in history have been, (voluntarily) practicing TDD seems quite innocuous. Even supposing TDD was a purely superstitious ritual, on par with an athlete refusing to change their “lucky socks” during game season, we cannot conclude that the practice isn’t at least valuable to the practitioner.

My topology is weak, but I remember enough to understand this. Indeed, one key advantage to homotopy is that if we have one thing, then we can reliably get the other thing. Refactoring, to me, means more than merely “I can improve this design safely”, but rather “Since I know how to improve designs safely, I don’t have to try to design systems as well as I possibly can the right time.” This provides immense freedom to alternate one’s energy between making it work and making it less stressful to change.

I never worked as a mathematician, but I was an enthusiastic student. Once we got past the basic forms of argument and the elementary proofs with “neat tricks” (sqrt 2 is irrational, there is no largest prime, the equivalence of DFAs and NFAs), finding a new(-to-me) proof was rarely an exercise in thinking hard then writing a sequence of steps, but rather of messing around until I found the key idea that made both ends of the argument fit together, then simplifying some steps to arrive at a proof that was both correct and easier to follow. Given this, sneaking up on a software design that satisfies us seems self-evidently sensible as an approach.

Moreover, as we’ve found in more-recent sports psychology circles, these rituals have less to do with false causation and more to do with creating the mental conditions in which the body spontaneously performs the right actions for the sport. As I like to say—and I don’t remember whether I stole it from somewhere, but I like it----superstition = routine + fear. We encourage the routine without the fear. Practising TDD helps me create the mental conditions for both focusing on wrestling with how That Thing Over There is supposed to work and for insight to visit, so that I realize why this code is really a tree and so Composite will make it much easier to work with. No fear involved.

Thank you.

Absolutely. I believe the combination of rigor with an eternal open invitation to the messiness of earnest exploration is uniquely valuable in both disciplines. In some sense, an overarching, global dedication to rigor is what permits us to “cash out” our positions when messiness is called for locally. We trust ourselves and our colleagues to re-engage with a more structured approach when the time and place are right, and there is an entire continuum between structured and unstructured approaches from which to choose. Knowledge of these enhances our toolkit, and wisdom affords us better and better choices of which tool to use, when.

This is a wonderful dictum. Too often, testing, generally, is associated with fear; it needn’t be.

The point about creating the conditions for success seems exactly right. I posed the much weaker form of the argument to wave away the gnats of “works for some of the people” and “works some of the time,” but I think your take does that without my strawman. I hope you don’t mind if I borrow it. :slight_smile:

Be well, and thanks for your insight.

1 Like