I love talking about tools and automating. I’ve written about having a dedicated developer tools team, and what you should automate. This time I want to talk about choosing between what I call vertical difficulty and horizontal difficulty when solving a problem.
Horizontal difficulty
Horizontal difficulty is difficulty that is associated with just doing the work as the current structure or tooling exists at that moment.
Consider the problem of moving a washer and dryer. If you have no tools and you just have to lift it, there is some horizontal difficulty involved.
In programming terms horizontal difficulty might look like writing a complicated SQL statement with multiple conditional joins because the data is all over the place. Or writing a web page without using a framework because your application doesn’t have one.
Vertical difficulty
This is the difficulty associated with mainly building tools or frameworks. It is the kind of difficulty that exists in simplifying a problem by going a layer up to “meta” solve the problem.
If you are familiar with Calculus in mathematics, Calculus is an example of what I would call vertical difficulty. Many mathematical problems are solved through the use of Calculus by taking the level up one higher and solving the problem there.
To keep with the same example of moving a washer and dryer, the vertical difficulty would be building a cart or dolly to move the washer and dryer. An important point here, which I will make again, is that in many cases the amount of raw effort required to build a dolly or cart, or even to figure out a way to procure one, will be equivalent to the effort required to move the washer and dryer.
In terms of code, vertical difficulty might be creating an error handling framework, creating a custom control for your web page, using views to simplify SQL data access, or even to repartition and move data to make a better model.
Where horizontal difficulty represents brute force, vertical difficulty represents mental fatigue.
What about that sawhorse?
If you are familiar with woodworking or construction, you will have no doubt seen a sawhorse. A sawhorse is platform that can be used to hold something so you can cut it.
Sawhorses are usually constructed on the jobsite before any other work begins.
Why?
Well, have you ever tried to hold a piece of wood and cut it straight? How about searching for different objects in your garage that you can prop the wood on so that you can get it high enough above the ground that you can put a saw through it?
Experienced craftsman build the sawhorse first. They don’t start cutting pieces of wood and then build the sawhorse. An experienced craftsman knows that by building the sawhorse first, he will save time by not wasting time on each cut. His cuts will be more accurate and he might just be able to bring that sawhorse to his next job.
Every time you sit down to solve a programming problem, you should think about whether or not you should be building a sawhorse first.
Are you saying always build the sawhorse?
No, not at all. If you are going to cut one piece of wood, do not build a sawhorse. If you are going to cut two pieces of wood, don’t do it either. I won’t tell you how many pieces of wood that it will take to pay off, but I will tell you 3 things:
- It doesn’t take many cuts for a sawhorse to pay back the time it takes to build it.
- The more sawhorses you build, the faster you get at building them.
- You are always wrong about how many cuts you are going to make. When you estimate 3 it might end up being 20.
Vertical vs horizontal difficulty
It is very important to weigh out the pros and cons of each before making a decision which way to go. I am, of course, going to try and lean you towards choosing vertical difficulty over horizontal most of the time, but ultimately it is up to you.
Let's look quickly at some pros and cons for each (very generalized.)
Horizontal
Pros:
- Can follow a well ridden path. Usually there is an example of how to solve the problem already. (Someone has done it before.)
- Less thinking, you just follow the approach and go; after some amount of hours you will be done. (Consider copy and pasting each cell of an html table to a spreadsheet, vs writing a program to parse it.)
- Less risk, you are very likely to get to your destination with minimal problems.
Cons:
- Boring. This is not really going to challenge that programmer blog reading brain of yours.
- You or someone else will be probably doing the same thing again. Solving the problem once only helps to beat down the weeds in the trail, but it doesn’t make it shorter.
- You might be building on top of a bad foundation. By adding one-offs as individual solutions to the problem, the general case can become more hidden. (If you want to solve the problem better later on, you make it harder each time you solve it the horizontal way.)
Vertical
Pros:
- Simplified working space. Once you solve a problem a vertical way, you end up building an abstraction that makes the problem seem easier at the lower level. (Think about connectors on your motherboard vs individually connecting each wire.)
- Reuse. Many times when you solve a problem the vertical way, you can reuse that solution to solve future problems in almost no time at all. (Build connector couplings for wires and next time you can just snap them together.)
- Bigger picture understanding of the system. When you take the time to go up a level and solve a problem, you can see the bigger picture better and can understand the system as a whole better. This will lead to better solutions and fewer mistakes later.
- You are developing a skill that is multi-purpose and can be applied more widely than a very specific skill which might be developed in a horizontal solution. (Thinking about working at McDonald's vs running several McDonald's.)
- Clean. Usually you will end up with less code. Less code means less bugs. Changes happen in one place instead of 50.
Cons:
- It can be hard mentally. It can require a higher level of skill. Not everyone who can solve the problem horizontally can solve it vertically.
- Higher risk. If you mess up along the path of the horizontal solution, you can probably go back a few steps and fix it. If you mess up along the vertical solution, you might have to scrap it and start over. (Building a house vs building a microchip.)
Okay, that’s it.
Wait, what? Did you say I forgot the biggest con of Vertical difficulty?
No, I didn’t. I left it out on purpose.
Vertical difficulty does not always mean it takes more time. Sometimes it is actually faster to do the vertical difficulty path even when “cutting one piece of wood.”
I have seen Perl programmers and gurus parse through text or whip up a meta-solution that can solve a problem faster than I could have done it manually once. And they have a script around to do it again.
I have seen VI wizards edit the heck out of a text file much faster than I could point and click to do the same thing.
Scripting languages and editors like VI are designed for solving vertical problems. When you are using VI and issuing commands to edit text, you are solving a vertical problem. You are operating at a high level to edit a text file.
Many times you will find that the vertical solution is not only faster the first time you implement it, but it also makes the solution almost instant the next time around.