Bugs in Programming


Introduction Webster's Collegiate Dictionary includes the following definition of bug: "an unexpected defect, fault, flaw, or imperfection." In programming jargon, "errors" known as "bugs". There are many apocryphal stories about the origin of this term and how it got applied to programming. In the most popular story, Grace Murray Hopper discovered that the Harvard Mark II computer was producing incorrect answers. When she examined the machine more closely, trying to locate the problem, she found a squashed moth, which was caught between the contacts of an electromechanical relay, preventing the relay from fully closing and conducting electricity; ergo, the first computer bug. In fact, she extracted the moth with a pair of tweezers and taped it into the operator's logbook with the comment "First actual bug found" -implying that the term was already in use at that time. Other stories about the first use of "bug" abound, so perhaps we shall never know the true entomology of this word.

The term bug became popular in programming to save the egos of programmers who could not admit that their programs were full of errors. Instead, they preferred to say that their programs had bugs in them. Actually, the metaphor is apt: programming bugs are hard to find; and although a located bug is frequently easy to fix, it is difficult to ensure that all the bugs have been removed from a program.

Debugging is the name that programmers give to the activity of locating and removing errors from programs (once the errors are known to exist, from testing the program). A programmer who is testing a program is often looking for new bugs to correct.

Categorizing Bugs This section categorizes bugs into four broad categories, each illustrated via an analogy that should help clarify its nature. Knowing the names of our enemies is the first step toward defeating them, so in the paragraphs below we define and explain the terms token error, syntax error, execution error, and intent error.

You might ask, "Why spend so much time talking about bugs when they should never occur?" The answer to this question is that programming requires an inhuman amount of precision, and although bugs should not occur in principle, they occur frequently in practice. Instead of expecting to write a completely correct program, we should expect to write a partially correct program. Then, we must become adept at quickly finding and fixing bugs by closely examining our programs (either by hand or with a special tool that helps us monitor an executing program). Whenever we change a program, we should be able to prove that at least one bug has been removed, and that our program has become more correct. It is common for novice programmers to change programs randomly, and as a result make them less correct. Avoid this temptation: debug your programs by carefully analyzing them, making only proven corrections that you understand.

Token Errors A token error occurs whenever our program contains a word or symbol that is not in Python's vocabulary or has been previously bound to a value.. As an analogy, suppose that one day we are standing on a street in San Francisco, and are asked by a lost motorist, "How can I get to Portland, Oregon?" If we say, "Just keep gngoi for ihegt hundred semil," we would have committed multiple token errors. The motorist is unable to follow our instructions, because he is unable to decipher some of the words from which the instructions are composed. Similarly, the Python interpreter must recognize each token (identifier, operator, delimiter, literal, and comment) in our programs.

Syntax Errors Even though the Python interpreter may recognize every token in a program, the program still may contain a syntax error. This type of error occurs whenever we use incorrect grammar or punctuation (according to the syntax rules of the Python programming language). Going back to our lost motorist, we might reply, "For keep hundred miles going eight just." Here, each word/token is individually recognizable as correct English, but we have combined them in a senseless and convoluted manner: the parts of speech are not in their correct positions for English grammar.

If a program contains any token or syntactic errors, the Python interpreter will discover and report them (typically in an Eclipse editor view). In both cases, the Python Interpreter has no idea of what we meant to say, so it will not try to correct the error; it will simply report it.

All these errors are called static errors, because the Python Interpreter detects them while we are typing the program, before we run it. Errors that occur when the program is running (or executing) are called dynamic (or run-time) errors. It is much easier to fix static errors.

Execution Errors Execution errors occur when the Python intepreter is executing code and discovers that it can't legally carry out one of our instructions (for example, dividing by 0). If it recognizes such a case, it raises an exception and terminates execution of the program (again, supplying some information about the error). Returning to our motorist trying to get from San Francisco to Portland, we might tell him to, "keep going for eight hundred miles." But, if he happens to be facing west at the time, and interprets our instructions literally, he could travel only a few miles before reaching the Pacific Ocean. At this point he would stop (we hope) and realize that he could not complete our instructions as given. This illustrates an execution error.

Intent Errors The final error category is the most insidious, because the Python Interpreter cannot detect and report this kind of error when it occurs. An intent error occurs whenever Python successfully runs our program, but the program doesn't produce the correct result. Coming back to our motorist who is trying to reach Portland from San Francisco; we could again tell him, "Just keep going for eight hundred miles." But if this time he happened to be facing south, he could successfully finish our instructions, but he would end up in Tijuana, Mexico not Portland, Oregon.

Remember that Python understands neither our programs nor what we indended them to do. It knows only how to run our programs. There is no way for Python to know what we intend the program to do, or detect that our program did not accomplish what we intended it to do.

Frequently, intent errors occur early in our programs and then later lead to execution errors. In such cases, the error may become manifest at a location that is different than the location that is the source of the error. Thus, we must carefully examine our programs, either from the beginning, or backward from the execution error, or end of the program, to locate the incorrect instructions.


Footnotes

Grace Murray Hopper Grace Murray Hopper (1907-1992) was a mathematician who joined the Navy as a WAVE during World War II. During her wartime service, she was a programmer who worked on the Harvard series of computers: the first general-purpose American stored-program computer. After the war she joined the Remington Rand Corporation, but also continued to be active in the Navy. During the 50s and 60s she worked on the development of compilers in general, and in particular on the programming language COBOL, which is used still extensively for business programming.

She retired from the Navy in 1986, having reached the rank of a Rear Admiral. Throughout her lifetime she was an active lecturer and educator; in her honor, the Association of Computing Machinery (ACM) has named a prize for innovative software developed by young computer scientists in her honor. They also hold the "Grace Hopper Celebration of Women in Computing" conference in her honor every year. The Navy also named a guided missile destroyer in her honor.

On the origin of Bugs: the OED The Oxford English Dictionary cites a 1889 newspaper quotation that said, "Mr. Edison, I was informed, had been up the two previous nights discovering 'a bug' in his phonograph." It is not know where this term first occurred in print.