The Spaghetti Limit: A theory of computer programming

Typical software development follows a brute force development strategy, where the functionality of the software is expected to be roughly proportional to the amount of development effort.

Managers who hire developers will be anxious to see results as soon as possible. They'll expect to see ongoing progress to justify continued investment.

As the software increases in complexity, unless the developers are extremely careful about its fundamental design, continued development will gradually become more difficult.

When a section of code has bugs or other problems, rather than rewriting the entire section, a developer will often add some kind of workaround. Over time, these workarounds, or hacks, start building up on top of each other. Eventually the code becomes incomprehensible - it starts to resemble spaghetti.

As the source code continues to spaghettify, the amount of time and effort required to add new features becomes greater and greater until eventually it reaches the "spaghetti limit". Continued development of the software starts to become futile. Developers spend all their time fixing old bugs. Eventually the cost of supporting the software becomes greater than the profit from its continued existence and the software dies.

One of the most valuable skills that a computer programmer can learn is how to limit the effects of spaghettification.

Stealth development

A piece of software may require months, or even years of effort before it is ready to be released. During this initial stage of development, it is inevitable that some parts of the code will start off being potentially buggy, inefficient, or otherwise less than perfect.

Under pressure to release something as soon as possible, developers often implement quick workarounds, thinking they'll have time to improve the code in later versions. This is where spaghettification begins, and once it starts, the software's eventual spaghetti death becomes inevitable.

The ideal way to avoid this is by rewriting the software, especially the foundations, over and over again until every part of it feels more or less perfect. Doing that might considerably delay the initial release, but once the software passes a certain threshold of stability, hopefully by version 2, the relative absence of spaghetti will allow more functionality to be added with less effort, and the extra investment will pay off.

This was the approach I attempted to take with 3D Flash Animator, and it worked well for a while. I wrote a pseudo-html interpreter for the application's dialogs and widgets. A year passed before the app even had an interface, but then being able to rapidly build scripted dialogs with built-in data-binding made future development much faster and easier.

Unfortunately there are still many common mistakes that developers make, as well as unavoidable external factors, which make spaghettification inevitable for all software projects no matter how stealthy they are. Only companies with deep pockets can afford to continue developing beyond the spaghetti limit.

People are generally resistant to other people's advice, and often you need to make common mistakes yourself in order to learn what not to do. Sometimes mistakes are unavoidable, but it's always helpful to be aware of a mistake while you are making it.

Backward compatibility trap

You will lose existing users if new versions are not backwardly compatible with older versions. However, backward compatibility makes it difficult to fix fundamental design flaws. At best, each new version accumulates a rat's nest of hacks that get added to adapt old data to new structures. Developers soon stop making significant design improvements out of fear of the bugs caused by the growing mass of backward compatibility spaghetti.

I should have abandoned backward compatibility between major releases of 3D Flash Animator. It is better to regularly lose half your users than to watch your software slowly die from lack of user enthusiasm.

Binary file formats

Backward compatibility problems are made worse by binary file formats. Unless you've invented some kind of miraculously flexible binary file format, the rigidity of your project files will seriously limit the future functionality of your software. I tried but failed to invent a flexible future-proof binary project file format for 3D Flash Animator. I only use hybridized versions of text-based XML now.

One of the worst binary file formats ever devised was the Flash file format. Until Flash version 9, the SWF file format made it almost impossible to do anything interesting with website animation. Years of my life were wasted trying to overcome its appalling limitations. With every new version of Flash I expected them to fix the mistakes and hopefully give me an opportunity to make something exciting out of 3D Flash Animator. Instead, Macromedia were either too inept, or too frightened of backward compatibility to make any worthwhile improvements.

By 2003 I concluded that there was nothing more i could do with 3D Flash Animator to get past Flash's limitations. Continuing to try was only turning the source code into spaghetti. Despite having obvious potential and many enthusiastic users, 3D Flash Animator was not a particularly useful piece of software. Development was put on hold for the next three years. Competing products like Swish and KoolMoves had the right idea - don't try to work around Flash's limitations, just make Flash simpler to use.

Adobe finally salvaged Flash when they released version 9 in 2006. The actual file format hardly changed, but the addition of ActionScript 3 was a revolution. In my opinion, ActionScript 3 is a sophisticated high performance language that is similar to, and is every bit as good as Java. The Flash 9 graphics API was cleverly devised and gave skilled Flash developers the creative freedom they were craving.

Unfortunately Flash 9 came too late to save Flash from developing a terrible reputation. Experienced developers shunned it and inexperienced developers found the new language difficult to learn. Flash's new layout framework, Flex, was cumbersome and slow to evolve, but without it, Flash was almost useless.

After the release of Flash 9, i devoted almost a year to upgrading 3D Flash Animator, hoping to take advantage of Flash's awesome new features. It was going to take time for Flash's new player to gain significant market share, so rather than completely abandoning the old Flash file format, I tried implementing a backwardly compatible fusion of ActionScript 2 and 3. It worked surprisingly well, but hacking together two incompatible formats turned 3DFA's graphics and scripting engines into a swirling mass of spaghetti. Bugs crept in that no amount of effort could fix. Crashes started happening without reason.

The final version of 3D Flash Animator was released at the end 2007. A few months later, Adobe open-sourced their Flash and Flex compilers. Despite having an enthusiastic user base, continuing to develop 3DFA was no longer worthwhile. It needed to be completely rewritten from the ground up using modern tools and techniques to take advantage of everything ActionScript 3 had to offer. But that would have taken years, and the results could not have been better than Adobe's own excellent Flex development tool.

The release of Google Chrome in 2008 changed everything anyway. The browser wars forced HTML's graphical animation abilities to rapidly improve. Modern web browsers can now do everything Flash can do. Adobe has done well to keep Flash alive in the form of Adobe Air for desktop and mobile development. I've used Air for app development and I love it. However, as far as website animation is concerned, Flash is more or less dead.

Google's V8 JavaScript engine was especially revolutionary. Before V8, script engines were usually stack-based byte-code interpreters. That's how Java, ActionScript, and 3DFA worked. In V8, however, the syntax tree is directly compiled into machine code like a C compiler. V8 was an order of magnitude faster than ActionScript, and several hundred times faster than 3DFA.

Spaghetti dependency

I made a huge mistake by writing software that depended entirely on a single target technology, Flash. For years my efforts were hamstrung by Macromedia's inability to innovate. Much of my time was wasted looking for hacks to overcome Flash's impossible limitations.

Whether it's Flash, HTML, PHP, or Java, most developers spend half their lives trapped by dependence on mainstream software that has been developed so far beyond its spaghetti limit that the rate of improvement becomes glacial. If and when revolutionary new versions are finally released, all those years of frustration spent working around the old limitations, often by building convoluted frameworks, becomes a forgettable waste of time.

I later tried adapting 3D Flash Animator to build Microsoft Silverlight animations, but the graphics engine was too tightly bound to the old Flash file format; and with unfixable bugs in the scripting engine and random crashes, the attempt failed. After that I lost interest in 3DFA and became fascinated by Firefox's XUL framework, Google's V8 engine, and the Webkit HTML library.

Wrestling the Windows API

In the 1990s, Microsoft realized that a modern operating system needed a modular object-oriented API. Their first attempt, Active-X, was a bad joke. But in 2002 they released a managed code library called .Net which looked a lot like their own version of Java. It was a great idea which suffered from Microsoft's typically flawed implementation. The quality of Microsoft software suffered for years as they stumbled their way through a painful evolution. Windows C++ developers were badly neglected for a while. Linux gained popularity.

3DFA's pseudo-html interface provided a degree of independence from the Windows API, but like every other programmer in the world at the time, I needed something better than the choices that were available. On one hand, the old multiple-document-interface API used by 3DFA was fast becoming obsolete. On the other hand I knew that embracing any new Microsoft API would mean that most of my time would thereafter be spent wrestling with new Microsoft spaghetti built upon decades of old Microsoft spaghetti. Too much of my life had already been wasted wrestling with Microsoft's deplorable APIs. Writing my own windowing system wasn't worth the effort, and alternative interface frameworks like Qt were not yet mature enough.

Now however, despite predictions of Microsoft's decline, I think their .Net gamble is finally starting to pay off. Recent versions of Visual Studio have been excellent, and developing desktop and mobile apps with HTML5 interfaces and .Net logic is a great solution with very low spaghetti overhead. Qt has embraced HTML5 too, making it a very good choice for new C++ projects.

Old tools and techniques

Visual C++ 6 was released in 1998 and was so successful that it is still popular today for maintaining legacy Windows projects. Development of 3D Flash Animator began in 1999, and for the next 8 years, 3DFA was almost entirely written using VC6. In my opinion, Microsoft didn't release another usable C++ compiler until Visual Studio 2008.

These days, C++ programmers build their applications using containers from one of a number of excellent template libraries like Boost. However, back in the 90s the choices were poor. VC6's support for templates was incomplete, and Microsoft's foundation classes were a diabolical mess.

I chose to develop my own specialized containers without generic templates, largely influenced by MFC's patterns. This had both good and bad consequences. Specialized containers handling most of the processing at the lowest level was an effective way to minimize spaghetti. However, without generic templates, I had to limit the number of types, just to keep my collections maintainable. That was probably my biggest mistake. These days, like everyone else, I use standard generic templated collections for everything.

Summary of lessons learned

Thanks for taking the time to read my theory. Please to leave a comment. I'll be happy to post your comments if they are relevant to the topic. Cheers, Rob.

Your email address
Your message