At the end of January we've reserved some time from our busy schedule to conduct a code retreat at PicScout.
For that propose we invited a very special guest, who was visiting Israel as a guest of the Software Craftsmanship community: Corey Haines.
Corey introduced himself to the team and then outlined the code retreat day.
We were supposed to implement a short program, called Conway's Game of Life in continuous series of sessions, each introducing and emphasizing a different idea/angle in the coding craft.
According to Corey, the idea was to perfect our knowledge and coding techniques by concentrated practice.
Just with the introduction, Corey mentioned very important thing: It is somehow a wrong perception that experienced/mature developers write perfect code.
Actually their code isn't beautiful (nor perfect), but the difference between the un-experienced and highly experienced developers is that their code will be perfect enough.
My own take on that is that only when you are an expert, only then you will be able to decide when this enough is enough (there are no rules, just experience and practice)
According to Corey, the purpose of the code retreat (to some degree) is to teach us how to seek a perfect enough code.
After a short introduction the fun began.
We coded in pairs for 45 min.
At the end of each session we deleted the code and started over from scratch.
And yes, you're not mistaken; We deleted the code.
Somehow, during the history of our profession we learned the unwritten rule:
Thee shell not delete any code.
Here is again my take on this: Deleting actually makes a lot of sense, since typing code isn't the real problem.
The real problem is reading (and maintaining) our code.
Therefore, the same writing 101 techniques apply when composing code.
Write, Re-read then Re-read again. If it doesn't make sense Delete it. Start over.
After deleting the code, we've reflected on what happened during the session. A few questions popped up and Corey provided short answers and directions.
In my opinion, the main idea was to let us to "find out" the right approach instead of providing a solid answer.
Swapping pairs contributed to the diversity of the solutions.
Each pair provided a unique solution and a unique approach that revealed different ways of solving a problem.
So what we did?
I. We started by exploring the problem.
Conway's game of life is a nice problem that cannot be solved in 45 min.
The first session was just to become familiar with the problem.
Needless to say that almost nobody (except the algorithm's team :) ) produced something coherent enough during this session.
II. Next we touched a sensitive topic, called a "better design".
You know what it is when you call somebody else and tell him that this isn't how he should build his software (guess what happens a few weeks later when somebody else review your code).
The idea in this session was that it is quite hard to find what is a "better" design. Therefore we discussed the 4 rules of simple design:
1. Tests Pass
2. Reveals Intent (good names)
3. No Duplication - repeat information and knowledge only once
4. Small (remove redundant, be lean and minimalist)
An interesting remark (with regards to 2) was that WE CAN use verbs to name classes.
Also here, some archaic (and not written rule) taught us that we should use only nouns as the class names.
Why is that? If it makes sense, if it reveals the content then we shouldn't limit ourselves to those rules.
III. On our third session we touched Test First.
We discussed where from we should start (obviously, from an empty, null or default case).
We discussed what we want to test or specifically what is the interface/action we would like to reveal during our test (a hint here will be: a tick() action that happens in the Conway's world)
We discussed how our test slowly and gradually reveal the interfaces and the behaviors of our objects (specifically we discussed why a cell needs to have a state)
IV. The fourth session introduced two pairing techniques.
a. A driver (who writes the code) and a navigator (who watches the driver)
b. A driver and a navigator are constantly exchanging their roles (like in a ping pong game)
The problem with the first technique is that it is done in a very statical way: The driver always drives and the navigator almost never touches a keyboard.
This is obviously quite boring!
The Ping-Pong technique is a better implementation of the Driver/Navigator. There are two forms of a Ping-Pong pairing:
a. Driver: Writes a test. Navigator: Passes the test
b. Driver: Passes a test and writes the next test. Navigator. Passes the test and then writes the next test
Eventually in this session we used a MUTE ping pong style when a driver writes a test and a navigator passes the test.
In addition, Corey introduced the "find the loophole" - the navigator will strive to write a wrong implementation (though in a clean manner) and the driver will strive his best to write the failing tests.
IMO, it was the best session, since there in silence you can really discover the power of the test first and pair programming techniques.
V. In that session Corey talked about the TDD and Test First techniques.
Corey explained the difference between the two and how our design should be changed due to the use of the TDD.
In addition, we were introduced with the following constrains on our code:
1. If statements are disallowed (unless these are guard clauses). If statement is a form of procedural programming and usually can be seen as the simplest form of polymorphism.
2. Explicit looping (for, foreach) are disallowed.
3. No primitives across method passing
4. No method with more than 3 LOC (lines of code)
I assume you guessed correctly, such constrains are really helping in creating more readable and maintainable code.
We wrapped the day by asking 3 Questions.
1. What if anything did you learn?
2. What if anything surprised you?
3. What if anything will you do differently moving forward.
I can definitely say that it was one of the most enjoyable days we had at PicScout and we surely learnt a great deal!