Tuesday, November 30, 2010

XP System Metaphor

The metaphor seems to be the most puzzling of the 12 XP practices. I'd been resistant to it because it seemed to obscure matters.

I'm quite taken with DDD and for me the heart of DDD is a well protected model that captures domain knowledge using the language of the experts. It seemed that the XP metaphor contradicted DDD's notion of ubiquitous language because the examples I'd been shown tried to replace the language of the domain with the language from the metaphor: the suppliers in our system are cows on a farm... no, not really.

Now I'm beginning to think DDD complimented by a system metaphor may be a brilliant solution. But it will depend on using the metaphor for the right part of the program.

I think the metaphor should be sought out for the parts of the system that are not clearly business domain, and further I think the metaphor should be strong and quite different to the domain. The metaphor represents the system architecture in all the ways that it is independent of the domain so I've started calling it the system metaphor.

With a good system metaphor the boundary between domain and system becomes clear: when the language of the metaphor and the language of the business mix there is an obvious clash of images. With a good system metaphor the architecture is made explicit in code: architecture is no longer an accidental fact of using certain libraries, accessing certain services, and calling one thing after another. With a good system metaphor explicitly representing the architecture and properly tested like any other code the system architecture should made easier to change and evolve independently of the domain.

Ron Jeffries gives an example of an agent-based information retrieval system using a beehive metaphor. The domain of information retrieval would use the language of information retrieval experts and those things which were part of the agent system and not part of the information retrieval would be coded using metaphor language; you know you're dealing with the system and not the expert's domain because you can see beehive words. Of course if the agents and the information retrieval were intimately linked in the domain then I'd avoid the metaphor and stick with domain language, but then I'd be looking for a metaphor to capture the system architecture around them.

Before I ever seriously looked at XP I had some good experiences with a distinct system metaphor. I was building a modular system for network printing, allowing specialist modules be plugged into drivers or moved to the printers themselves. What I built was pipe system, and in discussions and code I emphasised the metaphor of plumbing.

The plumbing metaphor allowed our specialist users to stay focused on their domains (colour processing, optimising streams of graphics primitives, font handling, etc) and to see their system needs differently to their domain problems. Thanks to the clear over arching structure that came from the metaphor, the program was very accessible to new developers. It was easy to explain, we'd draw pictures of pipes in sections that sparked imaginative thinking, (what happens if I change the order of pipe sections, or loop back on myself...), and it facilitated testing, (tapping the flow from a specific driver and pouring it back in elsewhere for generating test data, which later evolved into a network transmission system). We were able to effectively refactor the architecture without much fuss (changing the transfer mechanism between pipeline stages to improve error handling without touching the domain modules because the abstraction had kept them nicely separated).

But how do you find a system metaphor? You go looking for it. You also create the space for it. If the system metaphor is supposed to help you keep the system and domain separated then strive to keep them separate, try to talk about them with different language. If it's to makes sure that the architecture is something appropriately tested and structured then strive for those ends. And look for language which keeps the domain and system separate.

Be conscious of what goes wrong when system and domain get tangled, business logic in your controllers, changes to the user interface that break business functions, things that mostly happen because we don't distinguish between the domain and the system facilities we're using to deliver a program around that domain.

In the end it's a creative step, so get creative, try drawing the system without any boxes and arrows and without any words, think poetically, explain it to someone you respect who isn't a programmer.

And if you've had any success in this area, or if any of this leads you to write better programs please get in touch, I'd love to hear your stories.

Thursday, November 25, 2010

JavaScript: Curry Does The Work

curry is a common higher order function which isn't part of JavaScript on most browsers. However Prototype, Underscore, and many other libraries do offer it. The most up to date JavaScript implementations offer the bind function which can be used for the same job. I'm not going to show you how to implement curry nor attempt a generalised lesson, this is about how curry helps me with a refactoring.

In my previous post there was some really clear redundancy in the two wrapper maker functions. Lets make try to make that go away:
 
function wrapper_maker(before, after) {
return function(wrapped) {
before();
wrapped.apply(null, arguments);
after();
}
}

Which is great for the context push wrapper:

var contextualised = wrapper_maker(context_push, context_pop);

But how are we going to get those arguments for logging functions in place? The function curry does the work, (I'll use the Prototype version, it's pretty typical).

Basically curry makes a new function that behaves as if the arguments given have been pushed in front of other arguments so the following two bits of code do the same thing:

logger('abc');

var loggerX = logger.curry('abc');
loggerX();

This can be powerful when you want to pass a function that is generalised with parameters to another function that expects a function without parameters, which is what we need:

var logged = wrapper_maker(logger.curry('start'), logger.curry('done'));

And just like that curry gives a simple solution. It works when we want to add parameters to callbacks but don't control the code that will call our callback.

Refactoring to make our wrappers with wrapper_maker means we can add functionality to all of them without the duplication we would have needed in the previous post. Here's a refactoring that makes wrappers that pass back the wrapped function's return value:
 
function wrapper_maker(before, after) {
return function(wrapped) {
var result;
before();
result = wrapped.apply(null, arguments);
after();
return result;
}
}

Tuesday, November 23, 2010

JavaScript : Functions All The Way Down

Sometimes doing work with functions makes for more lines of code, but it also makes patterns of function calls reusable.

Here's an example that sandwiches our function call between some logging and some context management:

logger('start');
context_push();
do_stuff(data);
context_pop();
logger('done');

This kind of code gets dangerous if you have to repeat it. The problem is that we really want precisely that order of the surrounding functions. It's easy to transpose lines, or to update the pattern in some places but not others.

Functions come to our aid allowing us to write something like this:

logged(contextualised(do_stuff))(data);

That will guarantee the sandwiching, the first call will be matched by the last call, the next inner pair will match, and so forth. But actually writing those functions will add some code.

function logged(fn) {
return function() {
logger('start');
fn.apply(null, arguments);
logger('done');
}
}

function contextualised(fn) {
return function() {
context_push();
fn.apply(null, arguments);
context_pop();
}
}

The real value here is reuse. We can easily wrap any function now. And we don't have to call our function immediately, we can take the wrapped result and pass it as a parameter where ever it might be useful.

We can even make a general purpose function that create tools like logged and contextualised. I'll show an example of that when I talk about currying functions.

Sunday, November 21, 2010

JavaScript: eliminate temporary variables with higher-order functions

Functional Programming: it's the new cool! Any number of new languages striving to prove their functional programming credentials, and some old ones getting a boost. For most of it's life JavaScript has been trying to prove itself as an object oriented language, but you can also do some very neat functional programming style tricks with it. I think that the functional programming side of JavaScript is it's real strength.

So what's the big deal with FP? Didn't OO teach us that functions are the source of evil unstructured code? The FP response is that OO makes it too tempting to tinker with state, if you base you programming on storing and manipulating state then you will end up in a bad state sooner or later. Programming in an FP style often ends up with very little state and that state can be changed in only a very few places and narrow windows of time.

The following example uses a temporary variable to hold the current time and then makes an anonymous function to return it, the anonymous function is passed in turn as a parameter to another function. Old school procedural style code:

var temp = getTime();
fn1(function() { return temp; });

If you want to program in an FP style you've got to learn to find that temporary variable ugly, it's state, and it's an opportunity for mistakes. Your first instinct might be to inline the call to getTime() like this:

fn1(function() { return getTime(); });

But that would be wrong, getTime() is accessing changing state, the clock. The original code meant for it to be called just once when the anonymous function was first made. So we're going to isolate that call to changing state with something in a functional style:

function returner(x) { return function() { return x; } }
fn1(returner(getTime()));

Same functionality, no temporary variable. But it's not getting rid of the temporary variable that makes this functional programming, it's that I'm using a function that returns a function. That's the essence of higher-order programming: functions as the data that other functions work upon.

Things to notice: the helper function, returner() doesn't know anything about time, it's really just a tool for locking down some state, turning it into the return value of a function. Specifically we're using the stack to hold the state with the name x, and then we're closing on the value of x with an anonymous function so that we've still got access to it after the stack unwinds. As you do more in a functional programming style you might start building up a library of functions like these, and you'll discover that there are some standard functions that are effectively the patterns of the functional programming world, things like map, reduce, curry and others which I'll talk about in future.

One way to practice this is try writing your program with functions that have only one statement in the body, the return statement, and no var statements at all. All the work will be in the parameters you pass to your functions and what you can do in your return statements.

Take your time, this can be mind bending. You'll find as you apply this technique you'll have less need for variables and wrapper objects to hold state. Less state means less opportunity for errors because you can't be in a bad state. Having both the code organising benefits of OO and the state avoiding mindset of FP is a happy place for a programmer to be, and JavaScript give us that in a very simple package.

Saturday, November 20, 2010

JavaScript: varargs

The bad news is there's no simple varargs syntax in JavaScript. The good news is there are some workable patterns that can help if varargs are the right thing for your function.

arguments is an array like object, not an actual Array. It contains all the arguments passed to a function regardless of the named parameters. We're going to take that array like thing and turn it into a real Array, ignore the part that corresponds to the names arguments, then pull that array apart into variables. We'll assign some default values if we didn't get enough arguments.

function fn1(a) {
var args = Array.prototype.splice(1, arguments),
b = (args.length > 0) ? args.shift() : null,
c = (args.length > 0) ? args.pop() : {};

fn2.apply(null, [a, b].concat(args).concat([c]));
}

We use the splice method to get a real Array, and notice how we start at 1 to skip over our 1 named argument.

We use shift to take the left most of the varargs. Notice how we check if there are any arguments available and if not assign a default of null. We use pop to take arguments from the end of the list.

If there were more arguments they will be left in the args variable.

The body of this function calls another function, fn2, with the same arguments used for fn1. I'm using apply which takes an array of arguments so that I can put my variable number of left overs back in the middle.

Friday, November 19, 2010

JavaScript: Selection by Mapping

Very often we find ourselves branching in our code, and the most obvious way to do this is in an imperative style with if statements.
if (x === "case 1") { fn1(a, b); }
else if (x === 3) { fn2(a, b); }
else if (x === someObj) { fn3(a, b); }

That type of code gets tricky to read. There's lots of noise and repetition in the if and else statements, in the argument list on the function calls, and in the (x === ...) in the conditions. All that repetition can lead to errors. It's trickier to see what different about each case. There's also the opportunity to sneak in complexity increasing special cases.

The key to simplifying this is recognising that two things are happening: mapping of a condition to a function, and invocation of the function. We can separate those two things so the mapping of condition to function looks like this:
cond["case 1"] = fn1;
cond[3] = fn2;
cond[someObj] = fn3;

And the invocation looks like this:
cond[x](a, b);

In practice you'll be able to give a good name to cond that can help document what's going on as well.

However, variable arguments can be tricky, but we'll look at that in a later example.

javaScript tips and hints

I'm going to start writing my favourite JavaScript techniques here. I get better at what I do by trying to capture and name these technique. I hope they can help you get better at writing JavaScript, even if it's by reacting against my style.

My main focus will be higher-order and meta-programming techniques. I'm particularly interested in how list processing and functional programming style is such a natural fit for JavaScript. I probably won't spend lots of time on object oriented style although it's good to understand how object orientation can help with sharing and structuring code in serious JavaScript based applications.

Also, little and none of this will be written with reference to the DOM. JavaScript is bigger than the DOM with server side and mobile programming becoming important. Writing well engineered JavaScript is bigger than the browser. But writing browser based JavaScript is important and these techniques are still relevant there.

If this type of stuff is interesting to you then I strongly recommend Stoyan Stefanov's book JavaScript Patterns: Build Better Applications with Coding and Design Patterns.