TPP: From Dumb to specific, to generic

18 Oct 2021

Back in July, I had the chance to give a talk with our partner Skills Matter, in a series of Meetups called Thursday’s Matters.

During this talk I presented a number of exercises, a few of them frankly dumb, boring, or repetitive. The idea was to set the mood for repetitiveness and make the relation with typical TDD training, especially for those who are just starting. After all the repetitiveness, I showed an alternative solution, using TDD, but applying a “smarter” approach. How smarter you may ask? Well, not that much, since it’s an attempt at a formalisation already presented by Uncle Bob in his original post, but smart enough to point us in a direction where a solution developed by using TDD is generic enough.

The thought process behind this talk started some months ago when I was asked to run a TDD training. Like many TDD practitioners, I thought I knew what was necessary, but once I started preparing the sessions, there were a few topics unknown to me, at least formally. One of them was TPP or Transformation Priority Premise.

The Priority

The idea is simple. Uncle Bob presented a series of Transformations (code written to make a failing test to pass, as opposed to Refactorings) that a practitioner could use more or less in an “algorithmic way”. The algorithm or “premise” states that whenever facing a decision of “what test to write next”, write one that allows you to solve that given test, by applying the transformation that’s higher in the priority list (if possible). This will allow us to improve our solution and move towards a more generic code. Sounds simple, but it needed to be put into practice.

By the way, these premises are as follows:

({}–>nil) no code at all->code that employs nil
(nil->constant)
(constant->constant+) a simple constant to a more complex constant
(constant->scalar) replacing a constant with a variable or an argument
(statement->statements) adding more unconditional statements.
(unconditional->if) splitting the execution path
(scalar->array)
(array->container)
(statement->recursion)
(if->while)
(expression->function) replacing an expression with a function or algorithm
(variable->assignment) replacing the value of a variable.
 

So back then, I started reading and solving several times the same kata , roman numerals a rather simple exercise, and also read one article Applying Transformation Priority Premise to Roman Numerals Kata until things started to make sense. After all, that’s what’s supposed to happen when doing a Kata, you develop some sort of muscular memory, but with code.

Developing a solution

Starting to practice TDD is always difficult, especially when people already come with pre-conceived ideas and previous knowledge. Some people may not see the usefulness of writing tests first, after all, they already know what they’re doing. And trying to win them with terms like “baby steps” or “refactor on duplication” may be enough.

When it came to running the training, by pairing and guiding others into the particular topic of TPP,  I noticed that, although there is a particular order suggested (however, likely wrong as stated by Uncle Bob), it’s possible to jump to other transformations early, but following the rule of trying to apply the highest possible. By the end of my cycle, I had the chance to pair with another Craftsperson, Mark Gray, who suggested a few more “functional” moves. Then, the result is a lot like what I presented during the workshop, and different than the one presented by Pedro in his post. 

I wanted to run this workshop, because I wanted to win new practitioners or experienced coders with no TDD experience, with terms like “boring” or “dumb”, and then surprise them, more or less, with the TPP, and show them that it is possible to make the code evolve and generalize in a nice way.

It is worth mentioning that, like Uncle Bob in his original post, it was possible to show (and it was done in the talk) that the recursive approach was more simple than the iterative approach (shown by Pedro Santo’s post). This was possible by keeping a detailed commit history, which allowed me to move backward and try other transformations in order to get to a simpler solution. 

The solution looks like this, a very simple recursive algorithm that relies on a dictionary:

 

Some questions and next actions

Among the questions asked, one of the attendants asked why did I decide to move into the recursion. The answer wasn’t that simple, but can be summarised as a matter of seeing this exercise being developed several times, over and over again. I’d say it’s the product of practicing a Kata, like any martial artist would do, up until the moves are just reflexes. In the same way, being able to practice this Kata several times, allowed me to detect improvements and apply better transformations in order to generalise earlier, while keeping my code evolving step by step, without huge changes between one commit and another.

Additional reading

Original Uncle Bob’s article: https://blog.cleancoder.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html
Uncle Bob’s live demo: https://youtu.be/B93QezwTQpI
Code for this talk: https://github.com/jchacana-cdbcn/tpp-meetup
Applying TPP to Roman Numerals (Codurance blog): https://www.codurance.com/publications/2015/05/18/applying-transformation-priority-premise-to-roman-numerals-kata
Codurance Katalyst: https://katalyst.codurance.com/