The Grandfather’s Axe Pattern
A friend of mine is saddled with occasionally maintaining some TCL code, because a few years ago a programmer who was a “TCL fanatic” worked at her company and then moved on. Neither she nor anyone else in the company really loves TCL, and so she understands it only enough to maintain the damn program as required. Sometimes she goes all wistful at the idea of rewriting it all in C, in that “wouldn’t it be great if – but it ain’t never going to happen – but one can dream…” tone of voice.
Today, I am not going to comment on how suitable either TCL or C is for the job. I will take it as a given that, TCL is the wrong tool for the job and that C is the right tool for her to use – in her specific context. Because, of course, she and whichever reasons make her prefer C is an important part of her specific context.
However, I do want to comment on the “rewrite” bit. Rewrites are fraught with risk and are almost invariably more complicated that anticipated. See, for example, Uncle Bob on The Big Redesign in the Sky.
I’ve lost count of the times when I’ve had to make a “small” change to our system which we thought would “obviously maintain existing semantics”, only to find that the big bold leap to the new algorithm doesn’t work. In those cases, it has been of great value to retain both the old and the desired new implementation simultaneously, add asserts to our code that verify that both algorithms yield the same result, run the whole test suite, and let the computer pinpoint the fallout. Fix test failures, lather, rinse repeat.
And all that in the context of a small modification within a single existing system! I shudder when I contemplate the notion of trying to create a whole second system from scratch.
Luckily, there are better ways than a blank-slate rewrite. One option is the “Strangler Pattern” Martin Fowler described (also know as the “Strangler Vine Pattern”). The basic idea is to wrap the new system around the old system, siphon off more and more of the external-world inputs to the new application, until the new application replaces the old. Somewhat like a strangler vine replaces the tree it parasitises for scaffolding.
But there is another alternative, which I would call the “Grandfather’s Axe” pattern:
As the proverb says: “This is my grandfather’s axe: my father fitted it with a new stock, and I have fitted it with a new head.”
—Robert Graves, The Golden Fleece, p. 445
If you replace all the parts of something one by one, is it still the same thing at the end? Or think of Theseus’ Ship of Greek legend, which slowly, over time, had all its’ planks replaced. Is it still the same ship?

Lost argonauts, recently spotted in the present-day incarnation of Theseus' ship.
Instead of building a new system around the old one, replace parts of the old system one by one until only the new system remains. In the Strangler Pattern, the new system gets control before the old system does, and in that way intercepts more and more functionality. In this pattern, each part of the new system gets control at exactly the same point as the old part did, and functions within the context of the old system.
So, I would advise my friend:
- Install something like SWIG.
- Choose a simple, self-contained TCL function without dependencies to the rest of the TCL system. Reimplement it in C.
- Figure out how to get the old TCL code to call the new C function.
- With the mechanics of SWIG and TCL to C integration under your belt, next time you need to maintain a TCL function, try to move it to C first before extending its’ behaviour.
- Repeat until no TCL is left. This is the crux: if there’s no will to see if through, one is left with a more complicated system than one started off with.
- Discard the SWIG scaffolding.
One need not end up with a straightforward C port of the original system this way. As more and more of the system lives in the context you prefer, it should be easier to mould that part of the emerging new system into a new shape. That’s the premise: that the code is so much more expensive to maintain and modify in TCL that it would be cheaper and easier to modify it in C. If this premise isn’t true, there’s no point to this exercise.
Since the essence is to gain maintainability, I would also strongly advise taking the opportunity to explore Test Driven Development to bring the nascent new system under automated testing and gain a better handle on maintaining it.
However, I do feel compelled to point out that personally, I would never choose to move towards C in this way. I would use this technique to move away from C toward something like Python, Ruby, Lua, Scala or the like. Or, if appropriate, I would use this technique to isolate the speed-critical code into C subcomponents and the rest into a more malleable higher-level language – also known as the Alternate Hard and Soft Layers pattern.