Tuesday, May 17, 2011

Explorative Programming

Recently I've been struggling with a friend of mine about the actual meaning of Explorative Programming (or short ExP). The term Explorative is used here so that the pressure is put on the "exploring" part of it. I actually know it's not a proper English word but who cares :D

Anyways... Explorative programming - what is it all about?

Let's say you need to write the infamous "Calculator" class with the (also infamous) "add" method. In this particular case there's little to explore, right? You know (hopefully) that 1+3 equals 4 and there's nothing in the whole universe that will convince you otherwise :)
Let's explore this simple case in a little more TDD/ExP way. In TDD you'd write a class called (let's say) CalculatorTest. In that class you'd write a method with a @Test annotation (if you're using JUnit). That method would then instantiate your Calculator class (which does not exist yet) and call the method "add" (which does not exist yet) with some well known parameters that produce a well known output.

All good so far, meaning your test does not compile :).

So what you do next is that you add your class (preferably by means of some IDE's refactoring or what have you), then add the method (same as before - you actually can do this manually but who would do that when Eclipse and all the others are there to help you), fix the parameters (didn't you just write "def" to declare your variable to state that you don't really care what the fricken type is?) and finally after all those IDE-enabled steps (which let's be honest didn't take all that long) your test is compiling but failing. Great success!!!
The next obvious thing is to add the simplest thing possible which is to return the proper value from your function, then to add next test, see it failing, add the proper logic to satisfy both test cases.... you get the idea. This is TDD in its purest form as described by many mentors out there.

Where ExP is different is where the IDE needs to come in. Why for the love of god do you need a sophisticated tool to create a file for you when you actually don't need it? What you need is a class - not a separate file!

In ExP I propose that what you do is you do have the class (or method) you're testing but in the same file as your assertions. So for example:
def add(a, b) {
//the actuall implementation whatever it is goes here

assert add(1, 2) == 3
assert add(4, 5) == 9

Ain't that nice? You can sort of "explore" your domain "in place" without the need to have a sophisticated IDE to create unnecessary files for you (you're just creating a method for all you'd care at this point).

Let's examine a slightly more proper example for the actual "explorative" part of the thing, shall we?

Let's assume you're not alone in the world, which is a pretty good assumption in my personal opinion. Next let's assume you didn't write the code you're working on all by yourself (which in my personal experience is more than likely, or actually it's taken for granted if you add to the fact that you didn't write Spring or Hibernate all by yourself).

What you can't do at this point is to wave a magic wand and say "let it do what the client wants!". Instead what you can do is the next good thing which is to say "let's see what the user actually wants". And in the spirit of ExP what you'd do is to spawn a console of some sort within the currently latest version of your application (hello rails and grails!), sit down either alone (with tons of useless documentation trying to make your way thorough it) or with your actual customer, code 5 or 10 lines, write the assertions when the user says that it is the desired result.

Once you have it all figured out there's tons of knowledge that you better store for posterity! To do that you move the necessary bits and pieces where they belong, cutting your assertions in oh so many places into separate methods that'd satisfy your good taste for testing a single thing at a time and of course moving the class you just wrote to a separate file. From this moment on it's TDD only, my friend. You've got to keep'em separated.

Oh, and before I forget: the best thing in all this is you can actually use your eyes and brain to interpret the imperfect results before writing any assertions. Let's be hones: the computer (or the assertions rather) are only as good as you wrote them. If you already know what the actual outcome is (like in the case of some tests you might find on the net) it's fine to do it the old fashion way with separate tests and all that. What you do have to take into consideration while working with real life stuff is mostly the imperfect steps in between and how you can first spot them with sort of debuglets (I love this term!) or other means like the outcome of your script which is a debuglet all along.

I hope I've shed some light into this ridiculous term that I've tried to coin. Just as a word of caution: it might make no sense whatsoever when applied to your situation. What I strongly believe in is that it gives you the possibility to use simple text editor to do the TDD kind of thing with more freedom and options to choose from. That being said I officially declare that I don't use an IDE for anything and I mean it. IDE is bad for oh so many reasons I won't even go there. They make you a cripple when you need to actually come up with an idea of your own!

Oh! and before I forget: Once you've moved stuff back to where they belong you need to "integrate" your class with the rest of the system. That's where the regular TDD, IDEs and all kind of stuff that's floating around comes in.

Would you believe this all came to be from a single conversation with a supervisor that didn't actually end up being my supervisor at all? Funny how things play out...

There's a number of people that have advocated this style of programming. Recently on the 33rd degree conference Dierk Koenig showed how you'd go about writing your quicksort implementation. Previously Luca Bolognese showed the same kind of approach while presenting F# to the audience. It's all about learning, exploring and happiness :)

Have fun!

No comments: