Software 263 it. Find another, create a work-around, and so on. By doing this, we are effectively mechanically generalizing our solution. This is forbidden as it breaks the Turing limit, so we can’t mechanically solve a general logic problem above the logic limit. We need instead to use intuitive or creative thought. In our panic we did not stop, take a step back and engage our brain. Instead, we attempted, unsuccessfully, to blindly hack our way through the problem. If we eventually succeeded in perfecting the code this way, we would have broken a fundamental law of the Universe. Something nasty would have to happen to prevent it, such as rupturing the space-time continuum or an event equally horrible! Luckily something prevents this and keeps our Universe intact - BUGS! Bugs stop us breaking Turing’s limit. The next time you curse a bug, remember if they didn’t exist you'd be in danger of causing a logical paradox. There is no problem in redefining the domain and then creatively producing an all-encompassing design, but, you can’t patch and hack your way there. This theory of bugs leads to an explanation for some modern programming rules of thumb. Written specifications are valuable because they force you to lay out the whole problem. You don't need to be detailed regarding the depth, but should be expansive about the breadth, covering all the logical complexity. This might result in many details as a by-product, but a specification needs to delineate the edges of the problem space and not simply focus on a few key points. Writing the tests for the software in advance is helpful as it is likely to tell you early whether your design encompasses the whole problem space. Also, building a prototype, throwing it away, and then building the real thing can help greatly. It may be the only way to examine the edges of the problem space in detail. Armed with a full understanding, you can then imagine solutions to the complete problem in a single creative sitting. Whate