Tuesday, June 5, 2012

Another Stinkin’ Analogy

Yea, yea, I know. Programmers hate analogies. But I think that this attitude leads one to miss their importance. Sure the world is based on details -- facts -- but these facts are just chunks of information rooted in our physical existence. And more importantly this information isn’t mutually independent, it is tied by context to all of the other information floating about. These ties form a meta-layer of information that binds together the underlying information. It’s these higher level relationships that things like analogies, metaphors, similes try to address at a higher level of abstraction. Sure there are simplifications involved, and there isn’t always a one-to-one correspondence with all aspects of an analogy, but what there is a relationship that can be learned, understood, and applied back to help organize and utilize the facts. Facts don’t help unless you can turn them into actual knowledge …

This analogy comes in two parts. The first is simple: programming is like solving a Rubik’s cube. That is, it is a puzzle that involves figuring out a series of steps to solve it. Like Rubik’s cube there are many solutions, but there is often a minimal number of steps possible. Also, like solving the cubes, there are some states between ‘randomized’ and ‘solved’ where some of the sides appear solved, but the whole puzzle is not. Of course, programming has a significantly wider array of puzzles within it then just this one that need to be solved. They come in all sorts of shapes and sizes. Still, when coding it’s not unlike just working your way through puzzle after puzzle, while trying to solve them as fast as you can. It can often be a race to get the work completed.

The second part of the analogy comes in after the puzzle has been solved. Some people just toss the completed work into a big pile, but big software development needs structure not piles. In that sense, once each puzzle is complete it is neatly stacked to form an architecture. Usually the architecture itself has its own needs and constraints. The puzzles form the substance of the walls, but the walls themselves need to be constructed carefully in order for the entire work to hold together. Sometimes you meet programmers that don’t get that second half of the work. They think it’s all about the puzzles. But it really should be understood that the user’s don’t use the puzzles directly, they use the system and it’s the way the system holds together that makes the difference in their lives. The code could contain the cleverest algorithm ever invented, but if that’s wrapped in a disorganized mess, then its effect is lost on them.

Ok, I lied there is a third part to this analogy as well. I didn’t pick Rubik’s cubes lightly as the underlying type of puzzle. In the second part, obviously the cubes can also act as bricks in a larger structure, but there is still more. For anyone that has spend time solving Rubik’s cube from scratch -- no hints -- they know that it isn’t any easy puzzle. You have to work really hard to work out the mechanics of the combinations that will leave a solution in place. There are, of course, lots of books you can buy to teach how to solve the cubes quickly. Once you get the rules, it’s not very hard at all in fact these days kids compete for speed in times that are quite frankly somewhat unbelievable. Some programmers will argue that using Rubik’s cube as the iconic puzzle is a gross simplification, but I choose it on purpose since it has a rather dual nature. If you don’t know how to solve it, it is a hard puzzle. But if you do your homework first, you can get it down to an incredible speed. That ‘attribute’ holds true for programming as well. Computer languages are simple in their essence, and all libraries are essentially deterministic. If you dive in without any context, it is a difficult world where it almost seems magical how things get built. But if you gain the knowledge first to solve the types of problems you are tackling, then you can belt through them quite quickly. In a prior post I referred to it as ‘jogging for the mind’. It’s not effortless and it takes time, but it’s not nearly as hard as it is if you have no context. Write enough code, and coding becomes considerably faster and more natural.

In turning what we know into knowledge we need to collect the details together then find the rules and patterns that bind them. It’s this higher level that we apply back to our lives, to hopefully make them better in some way. This applies back to software development as well. Programming can be very time intensive. We rarely get enough time to really bring the work up to an exceptional quality. And it’s this deficit in resources that drives most of our problems in development. To counter this, we need to be as effective as possible with our limited resources, and it is exactly this point that comes right back to the analogy. I’ve spent my life watching programmers struggle in a panic to solve Rubik’s cube-like problems faster than is possible, but mostly because they didn’t just stop and find some reference on how to actually solve the puzzles first. They’ve become so addicted to doing it from scratch that they see no other way. Meanwhile, they could have saved themselves considerable stress by just looking up the answer. And to make it worse, because of the time constraints, they often settle on getting a couple of sides nearly done, not even the whole puzzle.

There are, of course, a huge variety of Rubik’s-like puzzles that we deal with on a regular basis, but easily the majority of them are well-understood and have readily available answers scattered about the World Wide Web. The time taken to find an answer is just a fraction of the time required to solve it yourself, and the more answers you find the more puzzles you can breeze through. The puzzles are fun and all, but what we’re building for the user is the structure of the system. Getting that done is considerably more fun.