I participated in a coding dojo recently in which some of the comments I heard caused me to think about the purpose of practicing code katas. It seems that many programmers, including some pretty advanced ones, don’t quite get the point.
We were reading about some code katas online so that we could choose one to do for the dojo. We came across a description of the Bowling Kata written by Robert C. “Uncle Bob” Martin. A couple of the guys quickly dismissed it when they saw Uncle Bob’s name. “He’s too prescriptive,” said one. “I don’t want to be told how to approach the problem,” said another. They looked for a write-up of the Bowling Kata that didn’t try to guide us in how to approach the problem.
They found one and we used it. All evening we kept running into silly little issues and speed bumps, such that we really didn’t get a lot of value from the whole exercise. We went down tool-related side paths, broke our development environment a couple of times, forgot what we were trying to accomplish, and started over multiple times. It never felt as if there was any goal or even a general direction. Despite the fact the group included some very fine professional programmers, I have to say it was not the best coding dojo I’ve ever been in.
Obviously, due to the sort of democratic and participatory event a coding dojo is, I have to accept a share of the blame for that. I actively chose not to make suggestions to bring the activity onto some sort of intentional course, because I wanted to see where it might go. In the end it went nowhere, but the experience led me to sit down and reconsider the reasons we do these things, and how we can get value from doing them.
The key point is that there are reasons for Uncle Bob’s approach to katas. Rather than getting to the point directly, I’m going to begin with a couple of rambling digressions, as per my usual style. If you are tl;dr (too lazy; don’t read much) then feel free to skip ahead a bit. Specifically, skip ahead to “Code Kata — How It Started.”
Why practice katas?
Here are a few representative definitions of the word kata in the context of martial arts:
- Kata (noun). [A]n exercise consisting of several of the specific movements of a martial art, especially a pattern prescribed for defending oneself against several attackers, used in judo and karate training. (http://dictionary.reference.com/browse/kata)
- Kata: A specific series of motions intended to train the body to react in a certain manner in specific combat situations. (http://www.ninpiden.com/glossary.html)
- A kata is a set of predefined actions that may be performed individually or with one or more partners. This is typically done to train in particular actions, combinations of actions, or action responses. (http://www.westerncircle.org/kbase/glossary.html)
What do these definitions have in common? The repeated movements represent recurring patterns in real self-defense situations. By internalizing the flow of these movements, we make them part of ourselves. To do so, we have to repeat the katas thousands of times, paying close attention to details with each repetition. Should we find ourselves in a self-defense situation, we will not hesitate (and therefore get beaten up) as we try to remember what our instructors told us to do when such-and-such a thing happens. We will just do it.
Will real attackers follow the prescribed sequence of moves of any given kata? Of course not. But their actions will consist of subsets of the same patterns of movements, one way or another, most of the time. Arranging the movements in a sequence our opponent doesn’t anticipate is the creative part, but we can’t get to the creative part without mastering the basics first. Mastering the basics entails a lot of repetitive practice of very basic techniques.
Why practice scales?
Music teacher Zac Johnson explains why it is important to practice scales (http://zacworld.com/scales.html):
There have been many times when I’ve been sightreading music in some situation, and lo and behold, up ahead there’s 3 measures of 16th notes, loaded up with sharps and flats and my first reaction will be to think to myself “Uh-oh, looks like a trainwreck approaching.” But then, when I get there, I suddenly realize, “Hey, it’s just the chromatic scale! I can play that!” Because I’ve practiced and learned the chromatic scale I’m able to get through it without any problems. As you get to know the scales you will begin to see them [in] all sorts of music you want to play, from Bach to the Beatles. Being able to recognize these patterns is one of the keys to becoming a great sightreader.
The website Essential Music Practice explains why it is important to practice scales (http://www.essential-music-practice.com/scales-practice.html):
Scales help the fluency of your playing, your sight reading, improvisation, composition and aural (listening abilities) as well as being useful for practicing techniques on your instrument. Scale practice helps you hear different keys and tonalities and identify patterns within music. Scales you know well also give you the opportunity to practice techniques without having to think about notes.
Thomas West shares the following personal story about the importance of practicing scales (http://www.thomasjwestmusic.com/apps/blog/show/3141602-why-do-i-need-to-practice-scales-the-value-of-tonal-literacy):
In my formative days as a clarinetist in high school, not a word was ever said to my band about practicing scales (or praticing much of anything, for that matter). We warmed up on a Bb Major scale and went straight to the business of learning our concert music by simply repeating it over and over with no rehearsal techniques whatsoever. […] As an undergrad music education student…my clarinet professor required us to occasionally perform a few predetermined major and minor scales as part of our juries, but since I was not a performance major, even there the expectations for mastering scales was not as it could be. […] It wasn’t until I took a graduate level course with band director emeritus Edward Lisk on his Creative Director series of books that my eyes were opened to what becoming a master of a musical instrument was really about. Mr. Lisk’s method revolves around using the circle of fourths/fifths as a tool to teach scales, chords, and just about any other concept you can imagine.
What do these explanations have in common? The purpose of practicing scales is to internalize patterns that are fundamental to most Western music. Having done so, a musician can play music expressively and smoothly without having to learn the notes by rote repetition. This entails repeating very basic patterns (scales, arpeggios, etc.) that seem quite boring in and of themselves thousands of times, paying very close attention to every detail with each repetition. As Thomas West’s story suggests, there is more going on than just the repetition of simple patterns. This sort of practice is a vehicle to deeper learning and, with time, true mastery of technique.
Who cares about being able to sight-read complicated music? Don’t we have ample time to woodshed our parts before any upcoming performance? There are two answers.
First: No. I used to play a lot of gigs. Here’s the drill: (a) Professional music is unionized, so you have to get paid at least scale, even for rehearsals; (b) Nobody wants to pay for rehearsal time because they aren’t selling tickets to the rehearsals; so (c) There aren’t any rehearsals. Sometimes there’s a meeting where the conductor talks through the roadmap for the show. Usually you just show up for the first performance. If you can’t sight-read your part, you’re out and you’re off the call list, too. There are plenty of other people ready to work. Besides that, a lot of these gigs involve backing up singers. Not all singers have the same vocal range. No one is going to pretty-print a transposed part for every temporary musician who plays in every town on tour. You have to be able to transpose your part at sight during the first performance with no mistakes, usually with many changes to the roadmap, and often in near-darkness. That’s the job. There are no excuses.
Second: Isn’t it boring to have to approach each and every new piece note by note, and to have no real understanding of the harmonic language or the underlying structure of the music? Isn’t it more fun to dive right into the deeper musical content of a piece right away?
Nothing prepares you for these things better than practicing all the scales multiple times every day. No musician ever out-grows this, just as no martial artist ever out-grows practicing katas.
Arrogance vs. mastery
Unlike martial artists or musicians, as a general rule programmers don’t practice what they do for a living. They just show up at work and start coding. Each time they encounter a slightly different problem than the last one, it’s a whole new world they have to figure out from scratch. How proficient at martial arts would Bruce Lee have become if he had approached his chosen field in that way? Could he have executed the one-inch punch if he never practiced punching technique or other basics? How proficient at music would Yo Yo Ma have become if he had approached his chosen field in that way? Did he wake up one fine morning and start playing the Saint-Saëns concerto perfectly, without ever having practiced scales or other basics?
Many of us enjoy participating in events such as coding dojos and code retreats. Most of the time, though, people tend to take a very informal and unstructured approach to the things they do in these events. Many participants aren’t there to learn. They’re there to drink beer and fart around. After all, those guys are already experts, aren’t they? If you don’t believe it, just consider the quality of 99.999999% of the code currently in production worldwide. That code didn’t drip from the sweaty backs of trolls into innocent computers; somebody wrote it that way on purpose. Only experts could have written that, right?
Here’s a comment posted on Hacker News a couple of years back:
[Programmers are] not really arrogant, they just come off as such. Programmers usually are pretty clever cookies and as a rule are more often right than wrong, even if the subject is not programming, that alone is enough to mark them as arrogant.
Hmm. Even if the subject is not programming, eh? Really? Try reading online comments from expert programmers on subjects like politics and economics. They are more consistent with Scott Adams’ observation in The Dilbert Principle:
Everyone is an idiot, not just the people with low SAT scores. The only differences among us is that we’re idiots about different things at different times. No matter how smart you are, you spend much of your day being an idiot.
Yeah, you and me both. From one idiot to another: We don’t need arrogance. We need mastery. So, what does that mean?
Meilir Page-Jones published a very interesting piece in 1998 that remains relevant to this day. It’s called “The Seven Stages of Expertise in Software Engineering.” Most programmers have heard of it and some have actually set aside tl;dr long enough to read it. In a nutshell it goes something like this:
- Stage 1: Innocent
- Stage 2: Exposed
- Stage 3: Apprentice
- Stage 4: Practitioner
- Stage 5: Journeyman
- Stage 6: Master
- Stage 7: Researcher
This model has a few inherent characteristics that I find helpful in understanding how professional growth works in our field:
- The time frames necessary to progress from Stage to Stage describe a geometric progression, not a linear one. It takes longer, for example, to progress from Stage 4 to Stage 5 than to progress from Stage 3 to Stage 4.
- The majority of professional programmers in the field are at Stage 4.
- Most people spend the majority of their careers at Stage 4.
- The majority of programmers never surpass Stage 4.
- Most of those at Stage 3 believe themselves to be at Stage 5 or 6. See: Lake Wobegon Effect for a highly scientific analysis.
- People at Stage 6 and Stage 7 have deep insights into principles of software development that are not apparent to people at earlier Stages. Note: This is the key point to understand in order to get the maximum value from code katas.
- People at Stage 6 and Stage 7 tend to be relatively unhelpful on real projects.
- The expression, “If you meet the Buddha on the road, kill him,” applies to anyone who self-describes as Stage 6 or Stage 7. Identify Masters by observing whom your colleagues at Stage 4 and Stage 5 regard as Masters. Pay attention to the man behind the curtain.
- In general, you cannot distinguish between the knowledge/skills of individuals who are at Stages above your own based solely on your own experience. You can tell that someone is more advanced than yourself, but you can’t tell by how much. You also can’t reliably tell whether Person A is more advanced than Person B, when both A and B are more advanced than yourself. You must rely on the observations of senior colleagues to make such determinations.
- The individuals who achieve Stage 6 or above couldn’t care less about achieving Stage 6 or above. They only care about lifelong learning. (See point #8 above.)
I would be surprised to hear Uncle Bob call himself a Master programmer. I am not surprised to hear just about everyone else in the field call him a Master programmer. When he suggests that we follow a certain path when working a coding kata, I think it is a good idea to try it his way. Every time I have done so, I have learned things I didn’t even realize were out there waiting to be learned.
If you think coding katas are supposed to be completely unstructured and loosey-goosey, then I encourage you to set aside tl;dr and read the following online articles. I’m going to be arrogant enough to prescribe a sequence for reading them, too.
Code Kata — How It Started
In “Code Kata — How It Started”, “Pragmatic Dave” Thomas reflects on the origin of code katas. Note that he started to play with some code with the purpose of learning something about effective programming. He wasn’t trying to write an actual application.
I think this is fundamental to the concept of practice. The goal isn’t to produce a commercially-viable software product. The goal is to explore some aspect of programming in order to gain deeper understanding of it. When you practice martial arts katas, you aren’t doing it because you expect street criminals to be impressed by your performance. When you practice scales, you aren’t doing it because you expect to walk out on stage at Carnegie Hall and perform scales. That isn’t the point.
Your learning objective can be anything. For instance, a few weeks ago I was curious to learn how it felt to approach problems from the perspective of various programming paradigms. I wasn’t trying to learn the basic attributes of each paradigm. I wasn’t trying to find out which programming language had the most pleasing syntax. I was trying to understand the differences in how it feels on a gut level to evolve a solution using each of three common paradigms — procedural, object-oriented, and functional. So, I wrote a reverse Polish notation calculator with a command-line interface in different languages, test-driving each solution. The languages had different characteristics with respect to paradigm and static vs. dynamic typing. I found it an instructive exercise, as well as enjoyable and relaxing.
That’s one possible goal in working coding katas. But deeper learning than that is possible, as well. To get down to that deeper learning, it’s helpful to have guidance from a Master programmer. Consider the lessons learned in the next bit of reading, and the manner in which they were learned.
The Transformation Priority Premise
In “The Transformation Priority Premise”, “Uncle Bob” Martin describes the idea of transformation as a complement to refactorings. While a refactoring is a micro-change that alters the structure of code but not its behavior, a transformation is a micro-change that alters the behavior of code without changing its structure. He further suggests that if we tend to prefer specific transformations over others when we are at certain points in the evolution of our design, we can avoid delays, rework, and impasses in development.
What is especially relevant to coding katas is the way Bob arrived at these ideas. Through working code katas thousands of times, he developed a deep sense of how designs tend to evolve and he began to perceive underlying patterns that suggested we could control that evolution even when we were not certain how the design would end up. It’s unclear whether he would ever have learned this if he had spent his career hacking out programs and never practicing. Read his piece and follow the path of learning he describes carefully, step by step.
Evolving Software and Improving Algorithms
Guilherme Silveira studied Bob’s article on transformation priorities and put the approach to the test to solve a problem that had different characteristics than the one Bob had used. He published his results in “Evolving software and improving algorithms”. By exercising the approach with a different problem, he exposed some potential improvements in the model.
You can discover results like this, too, but only if you take a rigorous approach to the kata and you work it with some sort of learning goal in mind. Starting with some random test case and letting things wander wherever they will isn’t going to yield a useful result like this except by pure chance. Read the piece and see how it played out, step by step.
Fib: The TP Premise
Bob found Guilherme’s experiment informative and expanded on it in Fib: The TP Premise. Deconstructing the results and folding them into his own learnings, Bob tweaked the list of transformations by adding tail recursion as preferable to arbitrary recursion and by adding a “last resort” transformation at the end of the list to add a case or else statement to an existing if statement. Read his write-up and learn how he reached these conclusions, step by step.
What does it mean?
What’s interesting to me in this is the fact that a useful approach was discovered as a direct result of practicing code katas thousands of times with rigor and attention to detail, and then through a series of iterative experiments involving more than one person the resulting model was improved and made highly practical and useful for real development work.
This sort of outcome just won’t result from drinking beer and farting around. If we’re going to do this sort of thing, then let’s do it for real and try to gain some deep learning from it. One way to improve our chances of learning is to pay attention to those who have gone before us and who suggest an approach to a kata that aims to guide our learning in some specific way. It is not a question of being “prescriptive.”
When the guidance comes from someone who is a genuine Master programmer, then it’s possible he/she is trying to show us something we don’t even know we don’t know. How can we find out, other than by exploring the suggested path?