Saturday, October 17, 2009

Fundamental Laws

OK, technically I'm under the influence. No, not drugs or alcohol, but rather Number Theory. In the last few weeks I've been consuming as much Number Theory as I can get my hands on. Sure, it's having some perverse effect on the way I see other issues, but occasionally one has to forgive the rigor, and just see it as a necessary impediment towards progress.

In thinking about it, I realized that Computer Science just doesn't have any strong "fundamental" theorems. Of course, "theorem" is a bit harsh (and Number Theory-ish) so I figure a softer title of "Laws" may be more appropriate. Here are some suggestions:

Fundamental Laws of Programming Structure:

1. All programming code is hard to write and has bugs.
2. The lower the code is in an architecture, the more you can re-use it.
3. The fastest way to develop code is by re-using it.
4. The best way to develop code is by deleting it.

Fundamental Laws of Spaghetti Code:

1. You can't understand it just by looking at it.
2. Repetitive code will always fall out of synchronization.
3. The work will always gets harder and slower as it progresses.
4. Fixing one bug creates several more.
5. You can't enhance the code if you are spending all of your time fixing the bugs.

Fundamental Laws of Enhancing Software:

1. Adding or upgrading to new functionality is very easy.
2. Upgrading the data and its schema is very hard.
3. It is often impossible or at least, very expensive to re-collect data or to "back-fill" it.
4. Getting the data collection right is far more important than getting the algorithms or code right.
5. Users care more about data, then functionality.

Fundamental Laws of Software Design:

1. Software development projects go on for as long as the software is actively used.
2. All software rusts (falls out of sync with modern technology), if it is not occasionally updated.
3. All code will eventually be "enhanced" to a newer, better version.
4. Software generally, only gets more complex.
5. It is orders of magnitude easier to add complexity to some code, then it is to remove it. Once complexity is entrenched it is very hard to remove.
6. There is no point initially agonizing over the perfect design, it is better to start with the simplest possible version and enhance it later.
7. The initial design phase for software should be as short as possible (but it should happen).

Fundamental Laws of Software Architecture:

1. A system is well-structured if and only if there are clear and consistent lines (APIs, libraries, components, etc.) separating and encapsulating each of the various sub-pieces within the system.
2. Well-structured software is easier to build.
3. Well-structured software is easier to test.
4. Well-structured software is easier to diagnose.
5. Well-structured software is easier to extend.
6. The software structure should match the development teams organizational structure.
7. The software structure should match the operational support services structure.
8. If there are any exceptions to the structural lines, then the software is not well-structured (only partially-structured).

Fundamental Laws of Commercial Software Products:

1. Not all code is industrial-strength code, even if it works.
2. The primary code is only a small percentage of the work (and the total lines-of-code).
3. Design is as important as functionality.
4. Packaging is nearly as important as functionality.
5. Most commercial products require more than 100,000 lines-of-code.
6. All commercial products require at very minimum, no less than two man-years of effort.
7. Releasing industrial-strength code is cheaper than just releasing code.
8. Bugs are inevitable, so support and distribution are key parts of the product.

Fundamental Laws of Testing:

1. All code has bugs, software should never be assumed to be bug-free.
2. There is at least one bug for every 200 lines of changed code.
3. It gets at least exponentially more time consuming to catch a larger percentage of bugs.
4. Every point of "integration" magnifies the number of bugs.
5. System level testing is the least expensive form of testing.
6. All testing resources are finite and not enough to thoroughly testing the entire application.
7. All tests have an inherent narrow scope (they test only a limited number of things).
8. All tests are "randomly" successful.
9. The results of testing don't change if neither the code, nor the test change.
10. All tests are code, and follow any of the normal laws of coding.
11. Tests are an expensive form of code.

I'll leave any discussion, justification or further information for upcoming blog posts (it gives me something to write about for the next few months).

Please feel free to add comments that are for, or against, any or all of these rules. Explanations would help too :-) If there are a lot of comments, this time I won't respond to each, but I may choose quote them later in the follow up posts.

Wednesday, October 14, 2009

The Value of Code

I've got a couple of interesting posts in the works, but for each one I'm having trouble with some of the essentials. It seems as if I've burnt out the left-hand side of my brain for a while. I've become mathematically challenged.

In the meantime, I figured I could get away with another short set of observations.

Recently I was installing a copy of Ubuntu Linux on my home machine.

I grew up using Slackware, moved into Debian and then flirted with Red Hat for a while, but I've definitely found 9.04 to be the nicest and cleanest installation I've ever used (it often took weeks to find working drivers for Slackware, way back in the days).

During the install, I started browsing through the available packages for download. There was a massive range of them available in the Synaptic Package Manager, and a whole lot more available from other sources. The sheer range of available software was staggering. There now seems to be an OpenSource version of just about every major piece of software out there, including the games.

This all took me back to twenty years ago, in University. We'd often spend nights and nights downloading little bits and examples of software code onto our home machines.

The University had kindly granted us access to this new network that connected many of the schools together (and a few companies). There was a list of magical "ips" (DNS didn't exist back then) that described modest FTP sites containing sample code and demos. We gorged ourselves on downloading. Anything and everything.

Up until we filled our XTs to the brim with code. Then we started copying it all onto 5 1/2 inch floppies.

One of the larger pieces available was a Unix'ish OS called Minux. I don't remember how big it was, but I do remember it took a significant effort to get it written on the floppies, built and then running on my XT. It even came with a C compiler. Somewhere on the other side of the world, it sounded as if Linus was out there indulging as well.

We were code junkies. We just couldn't get enough.

And it was amazing, because up until then, the only free code that I had access to was the little games published in magazines. They were often very lame, and would requires hours and hours to pain stakingly type them in, but they were a valuable source of learning. I often consolidated elements from them, into a little drawing program I was building. Puny by modern standards, but it felt huge at the time.

It was in those days, that there were still one-man shops out there pounding out commercial applications. Back the, the bulk of the teams for these new PC thingies were little shops, 3 or 4 people, and anything that even vaguely worked had some quickly growing value. Working code was worth something.

Not too many years later I knew a programmer that worked from home, mostly by himself, and had several reasonably known commercial successes. He produced some neat tools for versions in and around Mac OS 5 and 6. I can't say how much he made, but I do know that he was able to take his winters off to pursue a hobby, so it must have been fairly lucrative.

In one company, we purchased a library of print handlers from another one-man shop. I seem to remember a whole wave of "library" companies starting up to make their fortunes from selling good quality library code that you could include into your applications. It was a promising trend.

The OpenSource movement quietly flourished in the early nineties, but was quickly eclipsed by the dot com bubble. Code, or at least the hype from code, reached it very heights, but it was different then.

We didn't see it, but the "users" were quickly getting used to not paying for code. The Internet and the World Wide Web opened the doors to "free stuff", and flooded everything with it.

At the very moment when there was probably the largest investment ever, flowing into programming, the actual desire to pay for software was rapidly flowing away.

Since we were all seduced by high wages, easy jobs, a cut of equality and some crazy signing bonuses, we turned a blind eye to the underlying value of our work. After all, if you're going to get 2% of a multi-billion dollar company, do you really care if the users are refusing to pay for your latest and greatest?

But as always, what goes up ....

In the smoldering ruins, the value of software plummeted, and kept on going down. A half-decade ago, several wise business people told me that pure "software plays" were a thing of the past.

Software was worthless, hardware a commodity, and only in services was there any possible value. It was no longer a race to build bigger, better, more general applications. Instead, personal service, and a high degree of customization have become key.

Code was no longer important. In fact, so much so, that it was stacking up rapidly at OpenSource sites, waiting -- hoping -- for someone to download it. To give it a home, find it useful. It was like the island of misfit toys from the film Rudolph the Red Nosed Reindeer.

That precious resource that we chased so hard decades ago, has almost no value any more.

In truth, even with companies that still make their living from pure software plays, such as Microsoft, the code itself has become insignificant. If you could steal the code for Windows XP, and re-brand it, would anyone buy it?

Those software products that we all use have become "Brands", and the Brand is far more important than the code, or even the functionality. You use "Mac" or "Linux" or "Windows". The actuality of the code is irrelevant. It just doesn't matter anymore. You simply follow whichever Brand is more appropriate for the usage of the machine.

The same is pretty much true with the big machines as well. You use "Windows", "Sun" or "IBM". The Brand dictates everything else. Thus the databases that match are the Brands are "SQL Server", "Oracle" or "DB2". The environments are ".NET", "Java", and "Java/AIX or COBOL/RPG/iSeries". The tool-sets all follow from there.

So, overall I found it sad, as I scrolled through the massive list of available software titles on my Ubuntu box.

Sad, because our driving the value of code into the mud did little more than set the industry back decades. Sad because we gave away any incentive to be able to build better code. Sad because, the whole intent of OpenSource was to make code easily available, so that we could improve our work, not devalue it.

Without value, there is very little point in pursuing high quality technology. In the end, sales and users come from the strength of the Brand. It's the advertising, not the technology. The Brands get stronger, ever as the technologies bloat and decay.

I certainly saw this years ago, but it has been steadily getting worse. We don't have an open and competitive industry. We don't even have any innovation anymore.

The brands just senselessly copy each other, over and over again. It's become so entrenched that it seems to happen even within previously creative areas like video games.

I browsed through what looked like the OpenSource equivalent to each and every popular game from the last decade or so. It was a bizarre sort of flash-back, where I kept thinking "Hey, I remember playing THIS game" (and almost all of them were lower quality copies that seem to provide little new innovation on the original ideas or concepts).

In a way, though, it is probably somewhat of a natural progression. When something is new and unknown, just being involved is enough. But as it ages, the requirements get steadily higher. The bar only goes up.

Just being able to whack together something in your basement is no longer enough to get you into the commercial league. Just being able to make it barely run is no longer enough to keep you employed.

There are so many people now that can code to some degree or another that it has become tough for people to stand out in such a large crowd. Once an exclusive art, programming -- lightweight or heavy -- has simply become one shrinking piece of an ever growing puzzle. A small part of creating the solution. A single step in using computers to enhance and automate our process.

In some ways it is liberating. Now that code is essentially worthless, we should be able to find ways to quantify and share it. To give it away, so we can learn from it (instead of hiding it away).

Hopefully, instead of people just continuing to slap it together, we can really start to build up concepts of elegance. If code itself has no value, perhaps industrial strength code might still be worth something. After all, some day our users are going to figure out that their systems don't work very well, and that there are tangible (and possibly reachable) ways to fix them. We can't keep fooling them forever.