Pretty broad subjects. Difficult, too. in that they are largely unknowable. (If you knew there was an error, you would have fixed it!)
Can a program be error free? Probably not. (Old joke: The only error-free program is one that is not used). However, if you make a programming product that other folks use, you get errors pointed out quickly — and not always politely!
To minimize errors you first must design the program properly. There’s definitely an art to doing it. Clarity is key — and like any human activity, some are better at it than others.
Next, the code itself should follow standard conventions so that it is, well, readable. Readable? Yes, it is so easy to write “clever” code, that works, but in two weeks will look like gibberish. “Gee, what was I thinking of? Oh, now I see. But what is that variable? A typo?” If you’ve never programmed, this scenario is hard to imagine. If you have — you’ll be nodding!
As to side effects and unintended consequences, these are difficult to estimate before hand. With experience and, again, proper methods, some can be identified — best at the design process, before any coding takes place.
To illustrate, Consider an overly simple example:
We want to build a program that will let someone input numbers, one at a time and when a zero is input, add them all and output the sum. Pretty simple. Only tricky part is that the program doesn’t know how many numbers to expect. It has to “look” for a zero to know. (BTW, that would be a disaster in a large file of numbers, because a zero could be anywhere. You wouldn’t want to get a partial sum, just because one of the data items is zero.)
OK, I build it and, hooray, it works. For a test, I input 3, 7, 22.3, 0 and get a printout that says, 32.3. Perfect. All done.
I now give it to some friends and they input 42, 3, 16.5, #44, 0. What happens? I get a phone call. 😥 “Are you kidding? That program doesn’t work!” They send me the input data (and clever fellow that I am) I spot the ‘#’ immediately. What to do? My “perfect” program works — as long as the inputs are only numbers. It doesn’t know what to do with the ‘#’ sign. Responding, “Hey, careless people, check your inputs!” might not be optimal! Good way to lose friends (and customers!)
Probably the simplest solution is to modify the program. Put in an “If” clause that checks to make sure each input is a number. If not, stop, tell the user, and ask for a correct input. (That would take more code than the original program!) If the program is just for me, I don’t need that kind of “hand holding”. I know the limitations. Plus, I don’t want to bother inputting (and testing) the error catching code.
Here’s another potential problem — but much more subtle. Suppose that my code uses an internal memory location to hold the partial sums. So, as each number is read in it just adds it to whatever is in that location and stores the sum back. Certainly a reasonable way to do it.
But suppose that I make a mistake and, by accident, select a memory location that just happens to be inside another program on your computer. Now, my program works fine, but when you try (maybe next week) to use that other program it fails. (At least you’ll never know that I caused it!) We call that a “mad-bomber” error. Fortunately. most languages and operating systems now prevent that from happening. (Don’t tell anyone but it still can happen.)
I’ve been in the programming business for many years. Worked with some very smart folks.. We all have horror stories of an extremely well tested product failing almost immediately when others (who weren’t involved in the building) started using it. It’s very difficult to think of all of the possible side effects and errors. Building software products can be very humbling!
Over the years, professionals have developed good practices and methods to minimize many programming errors. But we still need clear, logical thinking.
That kind of thinking must start at training’s beginning.