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.