The history of “Taking Baby Steps”

The history of Taking Baby Steps

Let me tell you a story on how I thought about teaching other programmers how to take small steps to help them minimize the mistakes by focusing on a small thought.

Taking Baby Steps

Taking Baby Steps

A couple of years ago I was working on a legacy project, meaning I did not know anything about the business, and it was written in Delphi .Net which was totally unknown to me. I needed to translate this medium-sized code-base from Delphi .Net into .Net / Silverlight.

All the team was using a centralized source control system, namely TFS. But I needed to be sure that the steps I take are safe in my routine of translating the code from Delphi .Net to Silverlight, so I put in place Git. It helped me ensure that the steps I do locally are the good ones. I had done this before, using Git or SVN as a local source control while my team was using SVN as a centralized repository for the source code.

I started copying the Delphi code into C# class files and changing just the syntax so that the editor will not complain. This was my first step, then commit locally. In the beginning I did not know how to change the syntax fast enough so I did everything by hand. After doing that for a couple of classes I realized that I was repeating some actions that I could automate by using the replace function with some regular expressions or wildcards. Anyway the first milestone for committing was the editor check.

The second thing was to start and write tests for every interesting behaviour I saw in that code base. I was doing the usual steps when writing tests on legacy code: write the simplest test, see it is red, steal the output, put the output as the expected value and make the test green. Of course, the second milestone for committing locally was the green test. I promised to myself to commit only on green. I kept my promise around 95% of the time…

I continued adding all the necessary tests by applying the value sampling and behaviour slicing techniques. When I was happy that I wrote all the tests it was time for the fun part: REFACTORING :). I don’t know about you, but I love refactoring. Almost always I was using The Four Elements of Simple Design to take the refactoring decisions. I was refactoring small methods into the existing class and then those methods to new classes out of the initial class. Then I was adding some more tests needed because I was adding collaboration behaviour between the two classes. Again when all the tests were green was the third milestone to commit to the local source control.

When I was happy with the refactoring and with the design I took the next class and refactored that one and so on… until the big ugly class arrived! It took me two weeks and a half to refactor that one class! I extracted around 35 classes out of it and I was still not satisfied, so the number of classes reached around 45 in the end. But in this process it happened that I had to go back some 7 commits because I had made a terrible mistake in all that messy code: I had changed the behaviour of the initial code. I did not know exactly where I did that, but I looked into the good commit messages and I figured it out fast enough. Then it struck me: I cancelled almost two thirds of my day’s work! Why is that? WHY?? I was so annoyed so I started to figure it out.

It seems that the commit time increased drastically and the 7 commits happened at a distance of around 45 minutes. Then I realized that if I had made smaller steps I could have prevented this. I was just not focusing enough, and the commit contained so many changes so I needed to cancel all that work.

That is the time when I combined this frustration of mine with my desire to create a session for coderetreats where people would commit their code into source control repositories. The result was that I wanted to see how often I could commit, still respecting the rule: commit on green. In a couple of days, maybe one week I ended up lowering the average commit interval from around 45 minutes to 4 or 5 minutes. Some commits were really fast, after 30 seconds of work. Some other commits were longer at around 7 or 8 minutes. I started analysing those longer commits, and I understood how I could transform them into more shorter commits.

In the end I was happy that I was seeing progress, I was focusing on one thing, and the log of my Git looked great. If anyone wanted to ask me what I was working on, the answer was simple: git log 🙂

A couple of days after that I talked with Erik and told him about this idea: let’s make a session to force people to commit every two minutes. I can commit at 4 minutes, on average, on a legacy project where I don’t know the business and one of the languages, so they should be able to do this on a new code base with a simple problem and a language they know! Erik liked the idea from the start, and then refined it until the form of today. Then we gave this name “Taking Baby Steps”. Why? Because a small step is sure and steady, whereas when taking a large step you could be in danger of falling.

Steps

  1. Setup source control repository.

  2. Setup a timer for 2 minutes interval when you start.

  3. Write exactly one test

    1. If the timer rings and the test is red then revert and start over.

    2. If the test is green before timer rings then commit.

  4. Restart timer (no discussions in between timers)

  5. Refactor

    1. If the timer rings and the refactoring is not complete then revert and start over.

    2. If the refactoring is complete before the timer rings then commit.

  6. Restart the timer (no discussions in between timers)

  7. Go to 3.

  8. When session time is up delete the code.

I will come back with a post about the technique itself and the learnings triggered by facilitating this session this last year.

Please take a look on Erik‘s write-up about this workshop: http://talboomerik.be/2012/01/16/taking-baby-steps

Many thanks to Erik for creating this session together with me!

 

Update: Please read my other post about Taking Baby Steps here.

 

Baby steps image credit: http://pixabay.com/en/baby-monkey-blue-outline-symbol-23991/

13 Thoughts on “The history of “Taking Baby Steps”

  1. Interesting story about my favorite code retreat constraint. I really like how this exercise forces you to really keep your changes small, for exactly the same reasons you stated. It sucks to undo a couple hours of work just because you were taking too large steps. I started committing smaller changesets at work (of course with longer timeframes) and it already has paid of. Thanks for this insight!

    • Thanks for the comment. I’m glad that you favor this session on top of all the other coderetreat sessions.
      I totally agree that this incremental thinking changes the way you work. And this can be applied in any field, not only in programming.
      Keep up the good work, and I leave you with a question: how do you know that the step you take is small enough? I would like to know your opinion because I want to write a new post on this topic. Maybe you could help as you are using this technique.
      Thanks!

  2. Hi Adrian,
    I enjoyed your session at XP-Days and it significantly changed the style of my work.

    I also hosted my own session, for two friends, but I used slightly different rules. Especially I allowed discussions between resetting the timer as long as no code was changed.

    I wonder what your reasons are to disallow that.

    • Thanks for the appreciation.
      The main reasons I do not let people talk are that:
      – spoken words are an inferior type of communication compared to written words
      – communication through code is far superior to talking
      – if you talk then you don’t advance with the code base

      I often saw people preferring to talk, rather that writing code because it simply is unconfortable for them to write code with somebody they don’t know. The learning from talking is far inferior than the learning from writing code side-by-side with someone and figuring out each small detail together.

      Also for me the fact that someone needs to talk rather than write code is a symptom for a fuzzy incremental thinking. If I force people to write code, it may (or may not) result in an Eureka moment on what incremental (with small increments) thinking is about.

  3. Hi Adrian,

    as I had told you already at the XP-Days we did the exercise at our Softwerkskammer meetup in Munich, and like Jens I missed also the opportunity to gain your propagated experience of “communication by typing code” approach back than, but I loved it and had quite some insights though.

    I think you can feel when the change is small enough and if not: it was too big when the two minutes are over ;-). On the other hand we had several times the problem, that especially the implementation task to satisfy the next test was too big. In these cases we wrote a test for a simpler implementation method, that worked as helper method for the “bigger” implementation. That approach reminded me of the “component” design strategy of Kent Beck (from his Responsive Design workshop, e.g. see http://www.shino.de/2011/02/10/a-week-with-kent-beck/). It did its job and helped us then to be able to write the test and the now “not so big as before” implementation. I’m a bit skeptical if that is perfect, because of the questionable nature of the strategy (the YAGNI threat). Do you have an idea for a more “outside-in” approach by using something similar like mocking in contrast to the component strategy. On a bigger level (class) I would think about something like that but on method level inside a class. What is your opinion?

    In the “test and implementation” phase the rule is simple to apply. But I’m still not sure how you define “refactoring is complete”, because the refactoring usually consists of several micro refactorings (extract, inline, …); and these are already really small steps (but not each followed by a commit, that would be a bit too much, wouldn’t it?). Is it complete
    a) as long as the test still run?
    b) only if there is nothing more to improve (according to JB’s rules)
    What do you mean?

    Cheers (and sorry for ignoring the baby steps principle with this post 😉 ),
    David

    • Hi David,

      Related to the “outside-in” strategy, I cannot tell which is the best strategy. Everything depends a lot on the context. All these are techniques, each useful in some cases. As long as we know more techniques we can have a bigger tool bags to tackle all sorts of issues while developing software. I can tell you that I prefer using that techniques that offer me fast feedback and being sure that I build the right thing. Whenever I am not sure it means for me that I did not understand well enough what I need to do. The solution most of the times is to take very small steps to write “learning code”, which means I start discovering what some requirement really implies. Sometimes I take steps in wrong directions, but as long as the feedback loop is short and I can revert the last 2-3 commits (4-5 minutes of work), I am happy. This is waste, but it also shows me fast enough which is the wrong direction.
      Related to refactoring is complete I usually use some of the refactorings before the others. First of all I usually want to make sure that the naming is correct, from my current understanding of the problem. If it is not correct, that I start renaming all the items necesarry: classes, methods, variables, packages, etc.
      Then I want to spot duplication in my production and testing code. I start extracting duplicated code. Each extraction should be a step for me, followed by a commit on green.
      When I extracted some code I start re-analyzing the naming, if it is not that good I rename everything necessary. If more renamings should be performed, then I focus renaming some batch logically related, followed by a commit on green.
      Then I continue with the duplication until finished. In my view the refactoring is complete whenever the clarity is maximized, and the duplication is minimized, with respect to my current degree of knowledge about this problem.

  4. Pingback: - Club Agile Rhône-Alpes : Club Agile Rhône-Alpes

  5. Hi Adrian,

    The question when to finish the “refactoring” phase was meant regarding your excercise not in general. What do you mean?

    Interesting: J. B. Rainsberger starts with eliminiation of duplication, you with the clarification. I never though about it. But I think I have not yet a strict prio and still mix.

    Best,
    David

    • During the exercise I do the same steps for refactoring as in general. I care that the increments are small, and that I am always on green during the refactoring. I do recommend to the attendees to take more two-minutes refactoring sessions one ofter the other. This is what I do: divide the needed refactorings into smaller increments, having a natural order so that I can be always on green.
      In my view I cannot extract something if it is not clear to me, so I prefer to clarify it. Only after that I can minimize duplication and clarify again. For me it is a cycle between maximizing clarity and minimizing duplication. This cycle ends for me when I do not see any more duplication and when the names are good, with respect to the knowledge I have at that moment about the system.

  6. Pingback: Where Does Code Fit in People Over Processes? : Mozaic Works

  7. Pingback: Adrian Bolboaca : Mozaic Works

  8. Pingback: Where Does Code Fit in People Over Processes? – Mozaic Works

  9. Pingback: Adrian Bolboaca – Mozaic Works

Leave a Reply

Your email address will not be published. Required fields are marked *

Post Navigation