So far we've discussed the use of style to make your code clear and easy to read. But style doesn't stop at the printed page. A program is not only edited, debugged, and compiled; it is also used. In this chapter we extend our discussion of style to include how the program appears when it is in use.
As programmers, we encounter a large number of tools, utilities, and other programs. Some are a joy to use, letting us get our work done with a minimum of fuss. Others are a nightmare, with obscure and complex command sets.
In the early days of computing, machines cost millions of dollars and programmers cost only a few thousand. Companies could afford to keep several specialists around to translate management requests into language the computer could understand.
For the programmers, the early computers were very user-unfriendly. IBM's OS/360 required the programmer to interface with it using a particularly brutal language called JCL. The commands were cryptic; for example, "copy" was "IEBGENER", and specifying a file could easily take up three to five lines of JCL code.
Over the years, computers have dropped in price, and the cost of programmers has increased. Low prices have meant that more and more people can buy computers. High salaries have meant that fewer and fewer people can afford to pay a full-time programmer to run them.
For years, people have tried to come up with a set of laws to define what is user-friendly and what is not. Many of them involve complex standards and lots of rules; but the best law that I've seen governing program design is the Law of Least Astonishment: the program should act in a way that least astonishes the user.
Computers intimidate many people. (Those who aren't intimidated tend to become programmers.) Your first step in writing a user-friendly program is to put yourself in the shoes of the user. What does a user want from the system?
Almost all tasks done by computer were at one time done by hand. Before word processing, there was the typewriter. Before databases, there was the card file. A good program should be designed to emulate a manual task that the user knows. For example, a good word processor lets the user treat it like a typewriter. True, it adds a great many features not found on a typewriter, but at heart it still can be used like a typewriter.
A good example of a program imitating a manual procedure occurred when a business school graduate student was attending a financial analysis class. He noticed that the professor had a set of figures arranged in a neat set of rows and columns on the blackboard. Every time the teacher changed one number, he had to recalculate and write a new set of numbers.
The student figured that a computer could perform the work automatically, so he invented VisiCalc, the first spreadsheet program. Successful modeling brought this observant programmer a million-dollar idea.
Sooner or later, every user makes a mistake. When that happens, an error message usually appears. Writing a good error message is an art. Care and thought need to go into the creation of these messages.
So I consulted the book called Messages and Codes (aka The Joke Book), which was supposed to contain a complete list of errors, and it did--for all the codes except the IEH series, which was in the FORTRAN manual. Going to the FORTRAN book, I discovered that IEH240I meant "Job killed by fatal error." Of course, I knew it was a fatal error the moment it killed my job.
Remember that most users are not programmers, and they won't think like programmers. For example, a secretary was having trouble saving a memo and complained to the computer center. "Do you have enough disk space?" asked the programmer. The secretary typed for a second and said, "Yes, I see a message disk space OK." The programmer looked at the screen, and sure enough, there was the message:
Sometimes it is difficult to pick out the error messages from all the other noise being produced by the computer. A solution is to clearly identify error messages by starting them with the word Error:.
This humble program is devastated to report that it cannot accept the value of 200 for scale because the base and thoughtless programmer who implemented this program has thoughtlessly limited the value of scale to between 0.01 and 100.0. I implore your worthiness to reduce the scale and run this miserable program again.
For example, to get rid of a file, you use the command ERASE. But to get rid of a directory, the command is RMDIR. This is one of the many reasons MS/DOS is considered user-unfriendly. The command interface should be consistent. If you are going to use ERASE to get rid of a file, use ERASEDIR to get rid of a directory.
The GNU ispell program is another example of a program with a problem in consistency. This program checks spelling, and when it detects a misspelled word it produces a numbered list of suggested corrections:
To select a replacement, you just type in the number. Type a 2, and "Oualline" becomes "Mauling." The problem is that there can be more than 10 suggestions. In such cases, 1 is ambiguous. It can mean 1 or the first digit of 10. So the program forces you to type <ENTER> if you really want to select 1. Let's review the command interface:
As user-friendly programming has gained acceptance, help systems has improved as well. Today there are help compilers to aid the programmer produce context-sensitive help screens. The compiler also allows the programmer to embed cross-references in the text that let the user jump immediately to a related subject. Finally, there is an index of all topics that the user can search.
Help compilers are available for Borland's compiler and Microsoft's Windows development system. But even without a help compiler, every program needs to provide some help. More complex programs need context-sensitive help. Far too often, help systems are not designed into programs from the start, but instead as "if we have time" projects. This makes programs very unfriendly.
Occasionally a user will try to do something that causes permanent damage and loss of data to their system. A user-friendly program provides users with a safety net preventing them from doing something stupid unless they really want to.
Some users eventually develop into power users. You know the type--they know every command in the program, have an amazing set of tricks for getting around program limitations, and can quote long passages from the reference manual.
The user interface for the power user is different from that needed by the novice. Many programs provide accelerator keys, which allow the user to perform common commands with a single keystroke. For example, to run a program in the Borland C compiler you must type Alt-R to bring up the run menu, and then R to run the program. Power users can hit Control-F9.