CyberDojos

I've run a couple more CyberDojo's recently. The first was with Kevlin Henney during an onsite run of our Mastering Agile Practice course for commasoft in Bonn, Germany.

The second was for Mott MacDonald, in Croydon, England. Here's some feedback from the sessions:
  • an awesome afternoon!
  • It has been the single most useful training exercises I have attended at motts.
  • it was an excellent team building exercise and a fun introduction to some development concepts we're not familiar with, in particular pair programming and test driven development, but also the concept of 'deliberate practice'.
  • helped improve the cooperation within the team
  • Great!
  • I want more Dojos


Tests as specifications

The other day I was doing the yahtzee kata in C in CyberDojo and I got caught (not for the first time) by a classic gotcha...

I wrote my tests very very simply as follows:


...
static void two_pairs_scored_as_one_pair_is_spots_on_highest_pair(void)
{
    assert(...);
}

static void full_house_scored_as_one_pair_is_spots_on_the_pair(void)
{
    assert(...);
}
...

typedef void test(void);

static test * tests[] =
{
    two_pairs_scored_as_one_pair_is_spots_on_highest_pair,
    full_house_scored_as_one_pair_is_spots_on_the_pair,
    ...,
    NULL,
};

int main(void)
{
    for (int at = 0; tests[at] != NULL; at++)
        tests[at]();
    return 0;
}


I wrote another test and hit the Run-Tests button. But the new test didn't get run because I'd forgotten to add the name of the function to the tests array. Ooops. The new test compiled ok, and I'd tripped up thinking the test was passing when it wasn't even being run.

I've practised in CyberDojo enough that I don't get "sucked into the code" as much as I used to and when something like that happens there's now a fair chance I'll have enough awareness to notice it as it happens.

I stopped and thought about what had happened for a moment and I realized something. My problem was that I was writing the test function definition first. I should be writing the name of the test in the tests array first. And only once I've done that should I define it. There is a nice echo of the idea of Test First Design to this.

Of course in a language with reflection you only need to write the test function. Be that as it is, I like the the way the contents of the tests array lists the function names as specifications. In a language with reflection you don't get that.

The Secrets of Consulting

is an excellent book by Jerry Weinberg (isbn 0-0-932633-01-3). As usual I'm going to quote from a few pages. I know I've snippeted this book before, but I read it again and a really good book deserves a repeat snippet.
Consultants deal in change.
Consulting is the art of influencing people at their request.
..there is the problem of balancing certainty now versus uncertainty in the future.
Consultants are less adapted to the present situation, and therefore are potentially more adaptable.
The toughest problems don't come in neatly labelled packages. Or they come in packages with the wrong labels.
The bigness is not the horse.
The true expert can see multiple aspects of a situation, but the novice sees only... whatever is most conspicuous.
We all know that things tend to fall between cracks and that cracks occur at boundaries, where one system joins another.
For a trigger to be effective, the timing must be perfect: Too late means you're already committed to the troublesome action, while too early means you may forget again betwixt the cup and the lip.
There are always opportunities to jiggle.

Six memos for the next millenium

is an excellent book by Italo Calvino (isbn 0-099-73051-0). As usual I'm going to quote from a few pages:
Lightness for me goes with precision and determination, not with vagueness and the haphazard... (One should be light like a bird and not like a feather)...
... even correctness of style is a question of quick adjustment, of agility of both thought and expression.
... each value or virtue I chose as the subject for my lecture does not exclude its opposite.
Poetry is the great enemy of chance, in spite of also being a daughter of chance.
On folio 265 of the Codex Atlanticus, Leonardo begins to jot down evidence to prove a theory of the growth of the earth. After giving examples of buried cities swallowed up by the soil, he goes on to the marine fossils found in the mountains and in particular to certain bones that he supposes must have belonged to an antediluvian sea monster. At this moment his imagination must have been caught by a vision of the immense animal as it was swimming among the waves. At any rate, he turns the page upside down and tries to capture the image of the animal, three times attempting a sentence that will convey all the wonder of that evocation.
It is useless at every circle to invent a new form of metarepresentation.
What tends to emerge from the great novels of the twentieth century is the idea of an open encyclopedia, an adjective that certainly contradicts the noun encyclopedia, which etymologically implies an attempt to exhaust knowledge of the world by enclosing it in a circle.
There is a type of work that, in the attempt to contain everything possible, does not manage to take on a form, to create outlines for itself, and so remains incomplete by its very nature.
... the collection of objects of which only one specimen exists.
The classical author who wrote his tragedy observing a certain number of known rules is freer that the poet who writes down whatever comes into his head and is slave to other rules of which he knows nothing.

Synectics

is an excellent book by William J.J. Gordon (isbn 978-0060324308). As usual I'm going to quote from a few pages:
The word Synectics, from the Greek, means the joining together of different and apparently irrelevant elements.
Abstraction breeds more abstraction and more generality instead of leading to tough yes-no tests.
Words like intuition, empathy, and play are merely names put to complex activities in the hope that the naming of the activity will in fact describe it.
Human beings are heir to a legacy of frozen words and ways of perceiving which wrap their world in comfortable familiarity.
Synectics theory agrees with the conviction that a man does not know even his own science if he knows only it.
"All the crappy solutions in the world have been rationalized by deadlines."
He refused to recognize the fact that his search for the perfect problem was a way of avoiding failure in solving a less perfect one.
Invention is akin to painting for in practice, the element being constructed has the capacity to tell the builder what the next step should be. In invention this is much more critical than in engineering because the inventor is always attempting to do something new.
When this forgetfulness is formalized into a methodology, it reinforces the rejection of the commonplace.
Organic functions are unfinished, cylical, and self-reproductive... Synthetic functions are complete and more obviously subject to decay.
Conventions as abstractions from reality constitute a virtually complete and unassailable pattern, whereas the commonplace is infinitely repatternable.
The child who asks: "What's that funny noise?" is told the noise is thunder in such a way that speculation is supposed to stop... But naming the noise does not describe it. It does not answer the question, it kills it.

Why do car drivers brake?

Recently I wrote a small blog entry Why to cars have brakes? It's getting a lot of hits. Well, a lot for me. So naturally in my quest for even more hits here's a follow up...

Imagine you're in a car. Driving along. Why do you brake? I'm not asking what happens when you press the brake pedal? That's too easy (the car stops). I'm asking why…?


.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Here are two reasons:

Reason one: because there's danger ahead

This corresponds to a failing test. More specifically, it's when a test runs and asserts. A red. Perhaps there's a queue of traffic ahead (often a problem on the orbital car park known as the M25). Perhaps the road is closed off because workmen are working on it. Or maybe the local council has been meddling and the road is now a one-way-but-not-the-way-you-want-to-go road. Whatever the reason, something is not as expected.

Reason two: because you've arrived!

This corresponds to a passing test. A green. Wherever it is you're going, you've got there. Nothing unexpected happened. No traffic queues. No closed off roads. No meddling local council. Incredible!

In my entirely unscientific sampling almost everyone answers with the first reason. The second reason is not nearly as common. I find this interesting. I think maybe it's a reflection of the thinking statically vs thinking dynamically thing again. A perception that tests are most useful when they fire red. That tests which run to completion without incident are not so useful. But they are. Maybe more so.

Brakes help me stop. And stopping implies I'm already moving - I'm already going somewhere. But where? If I don't know where I'm going why am I moving at all? If I don't know where I'm going I'm just as lost as if I don't know where I am.

Tests are useful not just because of the I-didn't-arrive effect when they fail, they're also useful because of the I-did-arrive effect when they pass.

Another reason passing tests are really useful is the elves. But the elves will have to wait for another time.

Peopleware

is an excellent book by Tim Lister and Tom DeMarco (isbn 0-932633-43-9). As usual I'm going to quote from a few pages. I know I've snippeted this book before, but I read it again and a really good book deserves a repeat snippet.
Development is inherently different from production.
Most organizations don't set out consciously to kill teams. They just act that way.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted. [Tajima and Matsubara]
The manager's function is not to make people work, but to make it possible for people to work.
The trick isn't in the technology; it's in the changing of habits.
An age-old pattern of interior space is one that has a smooth "intimacy gradient" as you move toward the interior.
Employee turnover costs about twenty percent of all manpower expense. But that's only the visible cost of turnover. There's an ugly invisible cost that can be far worse.
It's only the right to be wrong that makes you free.
The structure of a team is a network, not a hierarchy.
Everyone quickly understands that the presence of the posters is a sure sign of the absence of hard work and talent.
The more you improve the way you go about your work, the harder the work will be.
The manager of a large project in Minneapolis has refused to move his people to the new quarters. ("New in this case just meant smaller and noisier.) Administrators were simply stunned at his refusal; they had never considered the possibility.

Just one more thing

is an excellent book by Peter Falk (isbn 978-0-099-50955-4). As usual I'm going to quote from a few pages
My object is to keep you awake.
I didn't stay in college the full four years. I quit after three months and joined the Merchant Marines. Men with one eye were not drafted and in the Merchant Marines they were not allowed to work on deck or below deck, but they could work in the kitchen. I sailed out as third cook. My specialty was pork chops.
About the third time I was late, even before I hit my seat, LaGallienne froze me with a question: "Why are you always late?" I said I had to drive down from Hartford. She asked coldly, "What do you do there? There are no theatres in Hartford. How do you make a living?" I told the truth. "I'm not an actor." She snapped back "Well you should be, now sit down."
I remember vividly that particular performance when for the first time I was suddenly startled by a new totally unexpected sound - a rich, deep authentic snore. Holy jamolies. There is someone on this stage that is sleeping - really sleeping.
I have never been arrested in the United States but I have been arrested in Paris, Moscow, Havana, Genoa, Belgrade, and Trieste.
Did he want to be buried or cremated? His answer to them was brief - "Surprise me."
"Here and there you'll find a raisin."
I was struck very early by the dramatic possibilities of playing a man who housed within himself two opposite traits.
For me The Princess Bride was a movie without a blemish, perfect for both kids and adults.

An Introduction to General Systems Thinking

is an excellent book by Jerry Weinberg (isbn 0-932633-49-8). As usual I'm going to quote from a few pages. I know I've snippeted this book before, but I read it again and a really good book deserves a repeat snippet.
The average scientist is good for at most one revolution.
"Proof" in its original sense was a test applied to substances to determine if they are of satisfactory quality... Over the centuries, the meaning of the word "prove" began to shift, eliminating the negative possibilities...
They know "better" - which is to say that their illusion is stronger.
We drive more slowly at night to give us more time to observe potentially dangerous situations.
More probable states are more likely to be observed than less probable states, unless specific constraints exist to keep them from occurring.
Things we see more frequently are more frequent: 1. because there is some physical reason to favor certain states, or 2. because there is some mental reason.
The Axiom of Experience can, like all of our principles, be turned around, to become a definition of what we mean by the word "like": Two things are alike if one in the present can be substituted for one in the past.
a "boundary" may not be infinitely thin, precisely so it can partake of both system and environment. Rather than separating, such a boundary connects.
We can learn, if nothing else, proper caution in our speech, which will inevitably lead to proper caution in our thought...

Test-driven development for embedded c

is the title of an excellent book by James Grenning (isbn 978-1-93435-662-3). As usual I'm going to quote from a few pages:
A good design is a testable design.
TDD helps you go faster... Slowing down is exactly what is needed to go fast!
Like TDD, if testing is hard, do it all the time - it gets easier.
Test automation is the gift that keeps on giving.
One test result is worth 1,000 expert opinions [Wernher von Braun]
You get a shot of testability with a portability chaser.
If we can identify a particular code smell, we have a better chance of eliminating the bad smell.
Shifting levels of abstraction should happen for a purpose.
Refactoring should be part of everyday development. It's not on the schedule, and you don't ask for permission to refactor.
The industry norm is for code to incrementally worsen with each change. We need to reverse that.
Dual-targetting, like TDD, has another benefit: it influences your design. Paying attention to the boundaries between software and hardware produces more modular designs.

why do cars have brakes?

I don't remember where I was when Kevlin Henney asked me:

Why do cars have brakes?

but I do remember his answer as a definite light-bulb moment. What's your answer?

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A very common answer is

to stop

or some variation thereof. In other words, to brake. It reminds me of the noun-verb thing again. Lights light. Irons iron. Compilers compile. Brakes brake. But that was not Kevlin's answer. Kevlin's answer was:

So you can drive faster.

His answer feels paradoxical which usually means there's a deep truth. Brakes allow you to stop when you want. Brakes allow you to stop where you want. Software tests are like brakes. They help you drive faster.

I'm also reminded of the P.W.Bridgman quote at start of chapter 6 of Jerry Weinberg's Introduction to General Systems Thinking:

...it is better to analyze in terms of doings or happenings than in terms of objects or static abstractions.

Thinking about brakes allowing you to stop is thinking statically. Thinking about braking allowing you to drive faster is thinking dynamically.

If you liked this post you might like the follow up Why do car drivers brake?.

A singleton refactoring

Here's a refactoring I often teach. It's particularly applicable if you're wanting to refactor legacy code. I'll show it in C++ in honour of the excellent developers at Promethean.

I'll start with a typical Singleton:

class singleton
{
public:
    static singleton & instance();
    void f(int value);
    int g(const std::string & path);
private:
    singleton();
    ~singleton();
};

Together with typical piece of client client code that I'm wanting to unit-test:

int client::eg1()
{
    stuff();
    more_stuff();
    int r = singleton::instance().g("Hello world");
    return yet_more_stuff(r);
}

My problem is that singleton leads to one or more external dependencies I'd like my unit-tests to bypass. My first step is to create an interface for the singleton:

class singleton_interface
{
public:
    virtual void f(int value) = 0;
    virtual int g(const std::string & path) = 0;
    ...
};

And then make singleton implement the interface. (The saving grace of singleton is that its methods are at least instance methods.)

class singleton : public singleton_interface
{
public:
    static singleton & instance();
    void f(int value);
    int g(const std::string & path);
private:
    singleton();
    ~singleton();
};

Now I can overload eg1 as follows:

int client::eg1(singleton_interface & instance)
{
    stuff();
    more_stuff();
    int r = instance.g("Hello world");
    return yet_more_stuff(r);
}

int client::eg1()
{
    return eg1(singleton::instance());
}

And finally, I can create singleton_interface sub-classes and use them in my unit-tests:

struct my_mock_singleton : singleton_interface
{
    explicit my_mock_singleton(int g_result) 
        : g_result(g_result) 
    {
    }
    void f(int value) 
    {
    }
    int g(const std::string & s) 
    { 
        return g_result; 
    }
    int g_result;
};

void test_client_eg1_hitch_hiker_is_42()
{
    assert(42 == client().eg1(my_mock_singleton(6*9)));
}