Friday, February 1, 2008

Why we can't build software like we build bridges

Many people say that software sucks. It has bugs, it doesn't work the way we want it to, it gets released late, it has useless features, it doesn't have a particular feature we need, the UI looks funny, I get epileptic seizures from its splash screen, etc. Granted, it's always going to be impossible to please everyone (duh), but with software people often find that they have a special kind of hatred (google "Windows Vista sucks" for a few examples). People say that if we build cars like we built software, they would crash every few miles, but you could completely fix them just by turning them off and then turning them back on. Obviously cars don't do that, so why must we suffer through software products that work exactly like that? Why is software so hard? Why can't we build software like we build bridges?

First of all, a bridge is a concrete thing (literally and figuratively). I can touch a bridge, I can walk across it, it can kill me if it falls on me, and it has a specific function that is well defined. On the other hand, software is an abstract concept. You can't touch it, you can't hit it with something, you can't drive across it, and it can't touch you (if it can, well, let's not go there). Software is an idea. It's an abstract concept of something concrete. Someone, somewhere said "I want to do some task and I want some software to help me with that task somehow" and then asked the question "how do I do that?" and unfortunately the answer is usually something along the lines of "it depends."

Software itself is really just a set of rules (or states, but let's not go there) that a computer has to follow. A programmer's job is to attempt to turn that abstract concept that the product owner is thinking of into a concrete set of rules that covers every possible scenario that may arise as a result of the user's interactions with the computer. There is no room for interpretation, there is only what the instructions say to do. If you try to do something that there isn't an instruction for, then the computer will most likely not behave in the way you want it to because the programmer didn't think of what to tell the computer to do when you did that. In order for software to be perfect, the programmer has to think of every possible state that the software could possibly ever be in and then program rules for all of them. This may sound impossible, and that's probably because it is.

A bridge is an easy thing to build. Someone has a problem that involves getting from here to there, and usually in between here and there is an obstacle of some sort that is difficult or impossible to traverse. The person usually has a means that they wish to use to traverse that distance which is pretty much limited to walking or driving. That makes it easy. It's possible to absolutely calculate the distance so we know how big it needs to be. It's possible to calculate the maximum possible number of people or cars or whatever that could ever occupy that bridge. You can calculate the strength of various materials to know exactly what to build your bridge out of. You can measure the stability and composition of the ground to know how you have to anchor the bridge. You can even estimate the external stresses that it's likely to encounter by observing the environment around the bridge.

This is all a complex process, but it still has an answer that exactly meets the criteria of "here to there without collapsing." Also (and possibly most important) is that once you build the bridge, nothing will change. The strength of the materials is constant (let's ignore things like rust here, but those can also be calculated at design time). The distance is constant. The environment is even constant within a certain range of parameters. The maximum load of the bridge is known (you can measure it) and it will never change. In fact, if any of those things ever did change, the bridge would most likely fail catastrophically.

Let me know tell you how a piece of software would look if it was a bridge. First, it needs to be able to connect any distance provided that there is a start point and an end point. If the distance changes, it should be able to lengthen or shorten itself as needed. Also, it needs to be able to hold up as many things as possible and should be able to change itself easily and quickly if it needs to support more things than it is currently able to. I should be able to build a bridge in one place and then immediately just copy that bridge to any other location that looks similar and has a start point and an end point. I also need to make my bridge support anything that looks like it might be able to cross a bridge, such as cars, people, trucks, airplanes, boats with wheels, motorcycles, tanks, trains, platypuses (platypi? whatever), and so on. Also, if it collapses for any reason, I should be able to just turn it off and turn it back on and it will be fine again. It should also be immune to all forms of external attack and should only allow people across who are authorized to cross the bridge. Finally, if any part of it is revealed to be prone to failure or vulnerable to attack or otherwise fails to allow objects across, I should be able to rebuild just that small part of the bridge and send it to you, where you can open the package and it will automatically install itself onto the bridge and fix your problem. That's the bridge you want me to build.

Do you know a piece of software that this could describe? A website. That's right, a fucking website looks like this. It needs to scale up and out, I should be able to patch it remotely if it's broken, it must be secure, it must be able to support anything that looks like a web browser and can speak HTTP, it needs to be installable on any web server that supports the language it's written in and HTTP, it should restart itself if I restart IIS, and it needs to work. And it's only a website. It's not AI, DSP, computer vision, distributed processing, self-modifying code, or anything else complicated like that, it's just a bunch of string concatenations. It's the "A" and the "P" of the LAMP stack. It's a couple of services out of hundreds on windows. And it is infinitely more complicated than building a bridge.

No comments: